tldraw 4.2.0-next.f100cedfc45b → 4.3.0-canary.03ae87dcc44b
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 +17 -7
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +5 -2
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/shared.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +63 -36
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +3 -0
- package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/crop.js +1 -0
- package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +1 -4
- package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +15 -7
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +2 -14
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/EditLinkDialog.js +11 -1
- package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +5 -4
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js +2 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +2 -1
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +17 -2
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +18 -16
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +3 -3
- package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +1 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +8 -0
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
- package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
- package/dist-cjs/lib/utils/frames/frames.js.map +2 -2
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
- package/dist-esm/index.d.mts +17 -7
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +6 -2
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/shared.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +65 -38
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -5
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +3 -0
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/crop.mjs +1 -0
- package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +1 -4
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +1 -4
- package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +15 -7
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +1 -4
- package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +2 -14
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs +11 -1
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +5 -5
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs +2 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +1 -4
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -1
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +17 -2
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/menu-hooks.mjs +1 -4
- package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +18 -16
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +3 -3
- package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +1 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs +1 -0
- package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +8 -0
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
- package/dist-esm/lib/utils/export/exportAs.mjs +1 -3
- package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
- package/dist-esm/lib/utils/frames/frames.mjs.map +2 -2
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
- package/package.json +10 -10
- package/src/lib/bindings/arrow/ArrowBindingUtil.ts +1 -1
- package/src/lib/canvas/TldrawSelectionForeground.tsx +18 -7
- package/src/lib/defaultExternalContentHandlers.ts +3 -4
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +2 -2
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +1 -1
- package/src/lib/shapes/arrow/arrowLabel.ts +1 -1
- package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
- package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +3 -3
- package/src/lib/shapes/arrow/shared.ts +4 -4
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
- package/src/lib/shapes/bookmark/bookmarks.ts +3 -3
- package/src/lib/shapes/draw/toolStates/Drawing.ts +4 -4
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
- package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
- package/src/lib/shapes/frame/components/FrameLabelInput.tsx +48 -24
- package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +10 -2
- package/src/lib/shapes/geo/toolStates/Pointing.ts +3 -3
- package/src/lib/shapes/line/LineShapeTool.test.ts +6 -6
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +5 -5
- package/src/lib/shapes/line/toolStates/Pointing.ts +1 -1
- package/src/lib/shapes/note/NoteShapeTool.test.ts +2 -1
- package/src/lib/shapes/note/NoteShapeUtil.tsx +6 -5
- package/src/lib/shapes/note/noteHelpers.ts +2 -2
- package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -1
- package/src/lib/shapes/shared/RichTextLabel.tsx +2 -1
- package/src/lib/shapes/shared/ShapeFill.tsx +3 -0
- package/src/lib/shapes/shared/crop.ts +1 -0
- package/src/lib/shapes/shared/useEditablePlainText.ts +7 -3
- package/src/lib/shapes/shared/useEditableRichText.ts +7 -3
- package/src/lib/shapes/text/TextShapeTool.test.ts +4 -4
- package/src/lib/shapes/text/toolStates/Pointing.ts +1 -1
- package/src/lib/tools/EraserTool/childStates/Erasing.ts +3 -5
- package/src/lib/tools/EraserTool/childStates/Pointing.ts +3 -16
- package/src/lib/tools/SelectTool/DragAndDropManager.ts +2 -4
- package/src/lib/tools/SelectTool/childStates/Brushing.ts +2 -6
- package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +2 -3
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +23 -15
- package/src/lib/tools/SelectTool/childStates/EditingShape.ts +2 -4
- package/src/lib/tools/SelectTool/childStates/Idle.ts +8 -12
- package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +1 -1
- package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +4 -12
- package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +2 -4
- package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +2 -4
- package/src/lib/tools/SelectTool/childStates/Translating.ts +1 -3
- package/src/lib/ui/components/Dialogs.tsx +2 -14
- package/src/lib/ui/components/EditLinkDialog.tsx +16 -6
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +6 -5
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
- package/src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx +4 -1
- package/src/lib/ui/components/menu-items.tsx +6 -14
- package/src/lib/ui/components/primitives/Button/TldrawUiButton.tsx +3 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +1 -0
- package/src/lib/ui/context/actions.tsx +25 -13
- package/src/lib/ui/context/events.tsx +1 -0
- package/src/lib/ui/hooks/menu-hooks.ts +9 -19
- package/src/lib/ui/hooks/useClipboardEvents.ts +12 -9
- package/src/lib/ui/hooks/useFlatten.ts +1 -2
- package/src/lib/ui/hooks/useTools.tsx +1 -2
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +1 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +1 -0
- package/src/lib/ui/hooks/useTranslation/useTranslation.tsx +2 -1
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +4 -6
- package/src/lib/utils/excalidraw/putExcalidrawContent.ts +8 -0
- package/src/lib/utils/export/exportAs.ts +2 -9
- package/src/lib/utils/frames/frames.ts +1 -1
- package/src/lib/utils/tldr/buildFromV1Document.ts +12 -17
- package/src/test/Editor.test.tsx +38 -12
- package/src/test/SelectTool.test.ts +11 -19
- package/src/test/TestEditor.ts +1 -4
- package/src/test/TldrawEditor.test.tsx +87 -40
- package/src/test/bindings.test.tsx +29 -25
- package/src/test/bindingsIndex.test.tsx +4 -4
- package/src/test/commands/createShape.test.ts +64 -0
- package/src/test/commands/createShapes.test.ts +15 -1
- package/src/test/commands/getSvgString.test.ts +2 -2
- package/src/test/commands/isShapeOfType.test.ts +44 -0
- package/src/test/commands/putContent.test.ts +1 -0
- package/src/test/commands/updateShape.test.ts +67 -0
- package/src/test/commands/updateShapes.test.ts +21 -5
- package/src/test/custom-clipping.test.ts +36 -35
- package/src/test/customSnapping.test.tsx +254 -54
- package/src/test/duplicate.test.ts +1 -1
- package/src/test/frames.test.ts +2 -2
- package/src/test/getCulledShapes.test.tsx +11 -3
- package/src/test/getShapeAtPoint.test.ts +2 -2
- package/src/test/groups.test.tsx +6 -3
- package/src/test/resizing.test.ts +9 -13
- package/src/test/selection-omnibus.test.ts +11 -11
- package/src/test/shapeutils.test.ts +1 -1
- package/src/test/styles2.test.tsx +1 -1
- package/src/test/styles3.test.ts +5 -5
- package/src/test/test-jsx.tsx +69 -57
- package/src/test/text.test.ts +15 -17
- package/src/test/translating.test.ts +6 -8
- package/tldraw.css +4 -6
|
@@ -83,28 +83,39 @@ export class DraggingHandle extends StateNode {
|
|
|
83
83
|
// Find the adjacent handle
|
|
84
84
|
this.initialAdjacentHandle = null
|
|
85
85
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
this.initialAdjacentHandle =
|
|
91
|
-
break
|
|
86
|
+
// First, check if the handle specifies a custom reference handle
|
|
87
|
+
if (info.handle.snapReferenceHandleId) {
|
|
88
|
+
const customHandle = handles.find((h) => h.id === info.handle.snapReferenceHandleId)
|
|
89
|
+
if (customHandle) {
|
|
90
|
+
this.initialAdjacentHandle = customHandle
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
// If
|
|
94
|
+
// If no custom reference handle, use default behavior
|
|
96
95
|
if (!this.initialAdjacentHandle) {
|
|
97
|
-
|
|
96
|
+
// Start from the handle and work forward
|
|
97
|
+
for (let i = index + 1; i < handles.length; i++) {
|
|
98
98
|
const handle = handles[i]
|
|
99
99
|
if (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {
|
|
100
100
|
this.initialAdjacentHandle = handle
|
|
101
101
|
break
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
// If still no handle, start from the end and work backward
|
|
106
|
+
if (!this.initialAdjacentHandle) {
|
|
107
|
+
for (let i = handles.length - 1; i >= 0; i--) {
|
|
108
|
+
const handle = handles[i]
|
|
109
|
+
if (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {
|
|
110
|
+
this.initialAdjacentHandle = handle
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
// <!-- Only relevant to arrows
|
|
107
|
-
if (this.editor.isShapeOfType
|
|
118
|
+
if (this.editor.isShapeOfType(shape, 'arrow')) {
|
|
108
119
|
const initialBinding = getArrowBindings(this.editor, shape)[info.handle.id as 'start' | 'end']
|
|
109
120
|
|
|
110
121
|
this.isPrecise = false
|
|
@@ -217,7 +228,7 @@ export class DraggingHandle extends StateNode {
|
|
|
217
228
|
}
|
|
218
229
|
const endChanges = util.onHandleDragEnd?.(shape, handleDragInfo)
|
|
219
230
|
if (endChanges) {
|
|
220
|
-
this.editor.updateShapes([{ ...endChanges, id: shape.id
|
|
231
|
+
this.editor.updateShapes([{ ...endChanges, id: shape.id }])
|
|
221
232
|
}
|
|
222
233
|
}
|
|
223
234
|
|
|
@@ -284,7 +295,7 @@ export class DraggingHandle extends StateNode {
|
|
|
284
295
|
if (!shape) return
|
|
285
296
|
const util = editor.getShapeUtil(shape)
|
|
286
297
|
|
|
287
|
-
const initialBinding = editor.isShapeOfType
|
|
298
|
+
const initialBinding = editor.isShapeOfType(shape, 'arrow')
|
|
288
299
|
? getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']
|
|
289
300
|
: undefined
|
|
290
301
|
|
|
@@ -341,10 +352,7 @@ export class DraggingHandle extends StateNode {
|
|
|
341
352
|
const next: TLShapePartial<any> = { id: shape.id, type: shape.type, ...changes }
|
|
342
353
|
|
|
343
354
|
// Arrows
|
|
344
|
-
if (
|
|
345
|
-
initialHandle.type === 'vertex' &&
|
|
346
|
-
this.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')
|
|
347
|
-
) {
|
|
355
|
+
if (initialHandle.type === 'vertex' && this.editor.isShapeOfType(shape, 'arrow')) {
|
|
348
356
|
const bindingAfter = getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']
|
|
349
357
|
|
|
350
358
|
if (bindingAfter) {
|
|
@@ -3,10 +3,8 @@ import {
|
|
|
3
3
|
TLCancelEventInfo,
|
|
4
4
|
TLCompleteEventInfo,
|
|
5
5
|
tlenv,
|
|
6
|
-
TLFrameShape,
|
|
7
6
|
TLPointerEventInfo,
|
|
8
7
|
TLShape,
|
|
9
|
-
TLTextShape,
|
|
10
8
|
} from '@tldraw/editor'
|
|
11
9
|
import { getTextLabels } from '../../../utils/shapes/shapes'
|
|
12
10
|
import { renderPlaintextFromRichText } from '../../../utils/text/richText'
|
|
@@ -109,7 +107,7 @@ export class EditingShape extends StateNode {
|
|
|
109
107
|
const textLabel = textLabels.length === 1 ? textLabels[0] : undefined
|
|
110
108
|
// N.B. One nuance here is that we want empty text fields to be removed from the canvas when the user clicks away from them.
|
|
111
109
|
const isEmptyTextShape =
|
|
112
|
-
this.editor.isShapeOfType
|
|
110
|
+
this.editor.isShapeOfType(editingShape, 'text') &&
|
|
113
111
|
renderPlaintextFromRichText(this.editor, editingShape.props.richText).trim() === ''
|
|
114
112
|
if (textLabel && !isEmptyTextShape) {
|
|
115
113
|
const pointInShapeSpace = this.editor.getPointInShapeSpace(
|
|
@@ -135,7 +133,7 @@ export class EditingShape extends StateNode {
|
|
|
135
133
|
} else {
|
|
136
134
|
if (selectingShape.id === editingShape.id) {
|
|
137
135
|
// If we clicked on a frame, while editing its heading, cancel editing
|
|
138
|
-
if (this.editor.isShapeOfType
|
|
136
|
+
if (this.editor.isShapeOfType(selectingShape, 'frame')) {
|
|
139
137
|
this.editor.setEditingShape(null)
|
|
140
138
|
this.parent.transition('idle', info)
|
|
141
139
|
}
|
|
@@ -3,11 +3,9 @@ import {
|
|
|
3
3
|
StateNode,
|
|
4
4
|
TLAdjacentDirection,
|
|
5
5
|
TLClickEventInfo,
|
|
6
|
-
TLGroupShape,
|
|
7
6
|
TLKeyboardEventInfo,
|
|
8
7
|
TLPointerEventInfo,
|
|
9
8
|
TLShape,
|
|
10
|
-
TLTextShape,
|
|
11
9
|
Vec,
|
|
12
10
|
VecLike,
|
|
13
11
|
createShapeId,
|
|
@@ -190,7 +188,7 @@ export class Idle extends StateNode {
|
|
|
190
188
|
// unexpected results when working "inside of" a hollow shape.
|
|
191
189
|
|
|
192
190
|
const hitShape =
|
|
193
|
-
hoveredShape && !this.editor.isShapeOfType
|
|
191
|
+
hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
|
|
194
192
|
? hoveredShape
|
|
195
193
|
: (this.editor.getSelectedShapeAtPoint(this.editor.inputs.currentPagePoint) ??
|
|
196
194
|
this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
|
|
@@ -201,13 +199,13 @@ export class Idle extends StateNode {
|
|
|
201
199
|
const focusedGroupId = this.editor.getFocusedGroupId()
|
|
202
200
|
|
|
203
201
|
if (hitShape) {
|
|
204
|
-
if (this.editor.isShapeOfType
|
|
202
|
+
if (this.editor.isShapeOfType(hitShape, 'group')) {
|
|
205
203
|
// Probably select the shape
|
|
206
204
|
selectOnCanvasPointerUp(this.editor, info)
|
|
207
205
|
return
|
|
208
206
|
} else {
|
|
209
207
|
const parent = this.editor.getShape(hitShape.parentId)
|
|
210
|
-
if (parent && this.editor.isShapeOfType
|
|
208
|
+
if (parent && this.editor.isShapeOfType(parent, 'group')) {
|
|
211
209
|
// The shape is the direct child of a group. If the group is
|
|
212
210
|
// selected, then we can select the shape. If the group is the
|
|
213
211
|
// focus layer id, then we can double click into it as usual.
|
|
@@ -356,7 +354,7 @@ export class Idle extends StateNode {
|
|
|
356
354
|
case 'canvas': {
|
|
357
355
|
const hoveredShape = this.editor.getHoveredShape()
|
|
358
356
|
const hitShape =
|
|
359
|
-
hoveredShape && !this.editor.isShapeOfType
|
|
357
|
+
hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
|
|
360
358
|
? hoveredShape
|
|
361
359
|
: this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
|
|
362
360
|
margin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),
|
|
@@ -507,7 +505,7 @@ export class Idle extends StateNode {
|
|
|
507
505
|
}
|
|
508
506
|
case 'Tab': {
|
|
509
507
|
const selectedShapes = this.editor.getSelectedShapes()
|
|
510
|
-
if (selectedShapes.length) {
|
|
508
|
+
if (selectedShapes.length && !info.altKey) {
|
|
511
509
|
this.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')
|
|
512
510
|
}
|
|
513
511
|
break
|
|
@@ -525,9 +523,7 @@ export class Idle extends StateNode {
|
|
|
525
523
|
const selectedShapes = this.editor.getSelectedShapes()
|
|
526
524
|
|
|
527
525
|
// On enter, if every selected shape is a group, then select all of the children of the groups
|
|
528
|
-
if (
|
|
529
|
-
selectedShapes.every((shape) => this.editor.isShapeOfType<TLGroupShape>(shape, 'group'))
|
|
530
|
-
) {
|
|
526
|
+
if (selectedShapes.every((shape) => this.editor.isShapeOfType(shape, 'group'))) {
|
|
531
527
|
this.editor.setSelectedShapes(
|
|
532
528
|
selectedShapes.flatMap((shape) => this.editor.getSortedChildIdsForParent(shape.id))
|
|
533
529
|
)
|
|
@@ -557,7 +553,7 @@ export class Idle extends StateNode {
|
|
|
557
553
|
}
|
|
558
554
|
case 'Tab': {
|
|
559
555
|
const selectedShapes = this.editor.getSelectedShapes()
|
|
560
|
-
if (selectedShapes.length) {
|
|
556
|
+
if (selectedShapes.length && !info.altKey) {
|
|
561
557
|
this.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')
|
|
562
558
|
}
|
|
563
559
|
break
|
|
@@ -604,7 +600,7 @@ export class Idle extends StateNode {
|
|
|
604
600
|
const { x, y } = this.editor.inputs.currentPagePoint
|
|
605
601
|
|
|
606
602
|
// Allow this to trigger the max shapes reached alert
|
|
607
|
-
this.editor.createShapes
|
|
603
|
+
this.editor.createShapes([
|
|
608
604
|
{
|
|
609
605
|
id,
|
|
610
606
|
type: 'text',
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Editor,
|
|
3
|
-
StateNode,
|
|
4
|
-
TLArrowShape,
|
|
5
|
-
TLHandle,
|
|
6
|
-
TLNoteShape,
|
|
7
|
-
TLPointerEventInfo,
|
|
8
|
-
Vec,
|
|
9
|
-
} from '@tldraw/editor'
|
|
1
|
+
import { Editor, StateNode, TLHandle, TLNoteShape, TLPointerEventInfo, Vec } from '@tldraw/editor'
|
|
10
2
|
import { updateArrowTargetState } from '../../../shapes/arrow/arrowTargetState'
|
|
11
3
|
import { getArrowBindings } from '../../../shapes/arrow/shared'
|
|
12
4
|
import {
|
|
@@ -29,7 +21,7 @@ export class PointingHandle extends StateNode {
|
|
|
29
21
|
this.didCtrlOnEnter = info.accelKey
|
|
30
22
|
|
|
31
23
|
const { shape } = info
|
|
32
|
-
if (this.editor.isShapeOfType
|
|
24
|
+
if (this.editor.isShapeOfType(shape, 'arrow')) {
|
|
33
25
|
const initialBindings = getArrowBindings(this.editor, shape)
|
|
34
26
|
const currentBinding = initialBindings[info.handle.id as 'start' | 'end']
|
|
35
27
|
const oppositeBinding = initialBindings[info.handle.id === 'start' ? 'end' : 'start']
|
|
@@ -58,7 +50,7 @@ export class PointingHandle extends StateNode {
|
|
|
58
50
|
override onPointerUp() {
|
|
59
51
|
const { shape, handle } = this.info
|
|
60
52
|
|
|
61
|
-
if (this.editor.isShapeOfType
|
|
53
|
+
if (this.editor.isShapeOfType(shape, 'note')) {
|
|
62
54
|
const { editor } = this
|
|
63
55
|
const nextNote = getNoteForAdjacentPosition(editor, shape, handle, false)
|
|
64
56
|
if (nextNote) {
|
|
@@ -90,7 +82,7 @@ export class PointingHandle extends StateNode {
|
|
|
90
82
|
if (editor.getIsReadonly()) return
|
|
91
83
|
const { shape, handle } = this.info
|
|
92
84
|
|
|
93
|
-
if (editor.isShapeOfType
|
|
85
|
+
if (editor.isShapeOfType(shape, 'note')) {
|
|
94
86
|
const nextNote = getNoteForAdjacentPosition(editor, shape, handle, true)
|
|
95
87
|
if (nextNote) {
|
|
96
88
|
// Center the shape on the current pointer
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateNode, TLClickEventInfo,
|
|
1
|
+
import { StateNode, TLClickEventInfo, TLPointerEventInfo } from '@tldraw/editor'
|
|
2
2
|
import { selectOnCanvasPointerUp } from '../../selection-logic/selectOnCanvasPointerUp'
|
|
3
3
|
|
|
4
4
|
export class PointingSelection extends StateNode {
|
|
@@ -35,7 +35,7 @@ export class PointingSelection extends StateNode {
|
|
|
35
35
|
override onDoubleClick?(info: TLClickEventInfo) {
|
|
36
36
|
const hoveredShape = this.editor.getHoveredShape()
|
|
37
37
|
const hitShape =
|
|
38
|
-
hoveredShape && !this.editor.isShapeOfType
|
|
38
|
+
hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
|
|
39
39
|
? hoveredShape
|
|
40
40
|
: this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
|
|
41
41
|
hitInside: true,
|
|
@@ -7,12 +7,10 @@ import {
|
|
|
7
7
|
SelectionCorner,
|
|
8
8
|
SelectionEdge,
|
|
9
9
|
StateNode,
|
|
10
|
-
TLFrameShape,
|
|
11
10
|
TLPointerEventInfo,
|
|
12
11
|
TLShape,
|
|
13
12
|
TLShapeId,
|
|
14
13
|
TLShapePartial,
|
|
15
|
-
TLTextShape,
|
|
16
14
|
TLTickEventInfo,
|
|
17
15
|
Vec,
|
|
18
16
|
VecLike,
|
|
@@ -228,7 +226,7 @@ export class Resizing extends StateNode {
|
|
|
228
226
|
|
|
229
227
|
if (shapeSnapshots.size === 1) {
|
|
230
228
|
const onlySnapshot = [...shapeSnapshots.values()][0]!
|
|
231
|
-
if (this.editor.isShapeOfType
|
|
229
|
+
if (this.editor.isShapeOfType(onlySnapshot.shape, 'text')) {
|
|
232
230
|
isAspectRatioLocked = !(this.info.handle === 'left' || this.info.handle === 'right')
|
|
233
231
|
}
|
|
234
232
|
}
|
|
@@ -528,7 +526,7 @@ export class Resizing extends StateNode {
|
|
|
528
526
|
// descendants (easy) but also flagging with behavior like "resize" or "keep absolute position" or "reposition only with accel key",
|
|
529
527
|
// though I'm not sure where that would be defined; perhaps better handled with onResizeStart / onResize callbacks on the util, and
|
|
530
528
|
// pass `accelKeyIsPressed` as well as `accelKeyWasPressed`?
|
|
531
|
-
if (editor.isShapeOfType
|
|
529
|
+
if (editor.isShapeOfType(shape, 'frame')) {
|
|
532
530
|
frames.push({
|
|
533
531
|
id: shape.id,
|
|
534
532
|
children: compact(
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Geometry2d,
|
|
3
3
|
StateNode,
|
|
4
|
-
TLFrameShape,
|
|
5
|
-
TLGroupShape,
|
|
6
4
|
TLShape,
|
|
7
5
|
TLShapeId,
|
|
8
6
|
Vec,
|
|
@@ -104,7 +102,7 @@ export class ScribbleBrushing extends StateNode {
|
|
|
104
102
|
|
|
105
103
|
// If the shape is a group or is already selected or locked, don't select it
|
|
106
104
|
if (
|
|
107
|
-
editor.isShapeOfType
|
|
105
|
+
editor.isShapeOfType(shape, 'group') ||
|
|
108
106
|
newlySelectedShapeIds.has(shape.id) ||
|
|
109
107
|
editor.isShapeOrAncestorLocked(shape)
|
|
110
108
|
) {
|
|
@@ -115,7 +113,7 @@ export class ScribbleBrushing extends StateNode {
|
|
|
115
113
|
|
|
116
114
|
// If the scribble started inside of the frame, don't select it
|
|
117
115
|
if (
|
|
118
|
-
editor.isShapeOfType
|
|
116
|
+
editor.isShapeOfType(shape, 'frame') &&
|
|
119
117
|
geometry.bounds.containsPoint(editor.getPointInShapeSpace(shape, originPagePoint))
|
|
120
118
|
) {
|
|
121
119
|
continue
|
|
@@ -407,9 +407,7 @@ function getTranslatingSnapshot(editor: Editor) {
|
|
|
407
407
|
const { originPagePoint } = editor.inputs
|
|
408
408
|
|
|
409
409
|
const allHoveredNotes = shapeSnapshots.filter(
|
|
410
|
-
(s) =>
|
|
411
|
-
editor.isShapeOfType<TLNoteShape>(s.shape, 'note') &&
|
|
412
|
-
editor.isPointInShape(s.shape, originPagePoint)
|
|
410
|
+
(s) => editor.isShapeOfType(s.shape, 'note') && editor.isPointInShape(s.shape, originPagePoint)
|
|
413
411
|
) as (MovingShapeSnapshot & { shape: TLNoteShape })[]
|
|
414
412
|
|
|
415
413
|
if (allHoveredNotes.length === 0) {
|
|
@@ -4,12 +4,7 @@ import { memo, useCallback, useRef } from 'react'
|
|
|
4
4
|
import { TLUiDialog, useDialogs } from '../context/dialogs'
|
|
5
5
|
|
|
6
6
|
/** @internal */
|
|
7
|
-
const TldrawUiDialog = ({
|
|
8
|
-
id,
|
|
9
|
-
component: ModalContent,
|
|
10
|
-
onClose,
|
|
11
|
-
preventBackgroundClose,
|
|
12
|
-
}: TLUiDialog) => {
|
|
7
|
+
const TldrawUiDialog = ({ id, component: ModalContent, preventBackgroundClose }: TLUiDialog) => {
|
|
13
8
|
const { removeDialog } = useDialogs()
|
|
14
9
|
const mouseDownInsideContentRef = useRef(false)
|
|
15
10
|
|
|
@@ -18,17 +13,10 @@ const TldrawUiDialog = ({
|
|
|
18
13
|
const handleOpenChange = useCallback(
|
|
19
14
|
(isOpen: boolean) => {
|
|
20
15
|
if (!isOpen) {
|
|
21
|
-
if (onClose) {
|
|
22
|
-
try {
|
|
23
|
-
onClose()
|
|
24
|
-
} catch (err: any) {
|
|
25
|
-
console.warn(err)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
16
|
removeDialog(id)
|
|
29
17
|
}
|
|
30
18
|
},
|
|
31
|
-
[id,
|
|
19
|
+
[id, removeDialog]
|
|
32
20
|
)
|
|
33
21
|
|
|
34
22
|
return (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T,
|
|
1
|
+
import { ExtractShapeByProps, T, TLShape, track, useEditor } from '@tldraw/editor'
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
3
3
|
import { TLUiDialogProps } from '../context/dialogs'
|
|
4
4
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
|
@@ -25,20 +25,28 @@ function validateUrl(url: string) {
|
|
|
25
25
|
return { isValid: false, hasProtocol: false }
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
type ShapeWithUrl =
|
|
28
|
+
type ShapeWithUrl = ExtractShapeByProps<{ url: string }>
|
|
29
|
+
|
|
30
|
+
function isShapeWithUrl(shape: TLShape | null | undefined): shape is ShapeWithUrl {
|
|
31
|
+
return !!(shape && 'url' in shape.props && typeof shape.props.url === 'string')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function assertShapeWithUrl(shape: TLShape | null | undefined): asserts shape is ShapeWithUrl {
|
|
35
|
+
if (!isShapeWithUrl(shape)) {
|
|
36
|
+
throw new Error('Shape is not a valid ShapeWithUrl')
|
|
37
|
+
}
|
|
38
|
+
}
|
|
29
39
|
|
|
30
40
|
export const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {
|
|
31
41
|
const editor = useEditor()
|
|
32
42
|
|
|
33
43
|
const selectedShape = editor.getOnlySelectedShape()
|
|
34
44
|
|
|
35
|
-
if (
|
|
36
|
-
!(selectedShape && 'url' in selectedShape.props && typeof selectedShape.props.url === 'string')
|
|
37
|
-
) {
|
|
45
|
+
if (!isShapeWithUrl(selectedShape)) {
|
|
38
46
|
return null
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
return <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape
|
|
49
|
+
return <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape} />
|
|
42
50
|
})
|
|
43
51
|
|
|
44
52
|
export const EditLinkDialogInner = track(function EditLinkDialogInner({
|
|
@@ -98,6 +106,7 @@ export const EditLinkDialogInner = track(function EditLinkDialogInner({
|
|
|
98
106
|
const handleClear = useCallback(() => {
|
|
99
107
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
100
108
|
if (!onlySelectedShape) return
|
|
109
|
+
assertShapeWithUrl(onlySelectedShape)
|
|
101
110
|
editor.updateShapes([
|
|
102
111
|
{ id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: '' } },
|
|
103
112
|
])
|
|
@@ -108,6 +117,7 @@ export const EditLinkDialogInner = track(function EditLinkDialogInner({
|
|
|
108
117
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
109
118
|
|
|
110
119
|
if (!onlySelectedShape) return
|
|
120
|
+
assertShapeWithUrl(onlySelectedShape)
|
|
111
121
|
|
|
112
122
|
// ? URL is a magic value
|
|
113
123
|
if (onlySelectedShape && 'url' in onlySelectedShape.props) {
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
TLPageId,
|
|
4
4
|
releasePointerCapture,
|
|
5
5
|
setPointerCapture,
|
|
6
|
-
tlenv,
|
|
7
6
|
useEditor,
|
|
8
7
|
useValue,
|
|
9
8
|
} from '@tldraw/editor'
|
|
@@ -306,6 +305,8 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
|
|
|
306
305
|
[editor, trackEvent]
|
|
307
306
|
)
|
|
308
307
|
|
|
308
|
+
const shouldUseWindowPrompt = breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer
|
|
309
|
+
|
|
309
310
|
return (
|
|
310
311
|
<TldrawUiPopover id="pages" onOpenChange={onOpenChange} open={isOpen}>
|
|
311
312
|
<TldrawUiPopoverTrigger data-testid="main.page-menu">
|
|
@@ -390,7 +391,7 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
|
|
|
390
391
|
>
|
|
391
392
|
<TldrawUiButtonIcon icon="drag-handle-dots" />
|
|
392
393
|
</TldrawUiButton>
|
|
393
|
-
{
|
|
394
|
+
{shouldUseWindowPrompt ? (
|
|
394
395
|
// sigh, this is a workaround for iOS Safari
|
|
395
396
|
// because the device and the radix popover seem
|
|
396
397
|
// to be fighting over scroll position. Nothing
|
|
@@ -399,7 +400,7 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
|
|
|
399
400
|
type="normal"
|
|
400
401
|
className="tlui-page-menu__item__button"
|
|
401
402
|
onClick={() => {
|
|
402
|
-
const name = window.prompt('
|
|
403
|
+
const name = window.prompt(msg('action.rename'), page.name)
|
|
403
404
|
if (name && name !== page.name) {
|
|
404
405
|
renamePage(page.id, name)
|
|
405
406
|
}
|
|
@@ -465,8 +466,8 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
|
|
|
465
466
|
item={page}
|
|
466
467
|
listSize={pages.length}
|
|
467
468
|
onRename={() => {
|
|
468
|
-
if (
|
|
469
|
-
const name = window.prompt('
|
|
469
|
+
if (shouldUseWindowPrompt) {
|
|
470
|
+
const name = window.prompt(msg('action.rename'), page.name)
|
|
470
471
|
if (name && name !== page.name) {
|
|
471
472
|
renamePage(page.id, name)
|
|
472
473
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
|
|
1
|
+
import { ExtractShapeByProps, preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
3
3
|
import { useUiEvents } from '../../context/events'
|
|
4
4
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
@@ -31,7 +31,7 @@ export function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps)
|
|
|
31
31
|
|
|
32
32
|
const handleComplete = () => {
|
|
33
33
|
trackEvent('set-alt-text', { source })
|
|
34
|
-
const shape = editor.getShape<
|
|
34
|
+
const shape = editor.getShape<ExtractShapeByProps<{ altText: string }>>(shapeId)
|
|
35
35
|
if (!shape) return
|
|
36
36
|
editor.updateShapes([
|
|
37
37
|
{
|
|
@@ -54,6 +54,9 @@ export function DefaultRichTextToolbarContent({
|
|
|
54
54
|
// todo: we could make this a prop
|
|
55
55
|
const actions = useMemo(() => {
|
|
56
56
|
function handleOp(name: string, op: string) {
|
|
57
|
+
// Check if the editor view is available before calling operations
|
|
58
|
+
if (!textEditor.view) return
|
|
59
|
+
|
|
57
60
|
trackEvent('rich-text', { operation: name as any, source })
|
|
58
61
|
// @ts-expect-error typing this is annoying at the moment.
|
|
59
62
|
textEditor.chain().focus()[op]().run()
|
|
@@ -109,7 +112,7 @@ export function DefaultRichTextToolbarContent({
|
|
|
109
112
|
}, [textEditor, trackEvent, onEditLinkStart])
|
|
110
113
|
|
|
111
114
|
return actions.map(({ name, attrs, onSelect }) => {
|
|
112
|
-
const isActive = textEditor.isActive(name, attrs)
|
|
115
|
+
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false
|
|
113
116
|
return (
|
|
114
117
|
<TldrawUiToolbarButton
|
|
115
118
|
key={name}
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TLBookmarkShape,
|
|
3
|
-
TLEmbedShape,
|
|
4
|
-
TLFrameShape,
|
|
5
|
-
TLImageShape,
|
|
6
|
-
TLPageId,
|
|
7
|
-
useEditor,
|
|
8
|
-
useValue,
|
|
9
|
-
} from '@tldraw/editor'
|
|
1
|
+
import { TLPageId, useEditor, useValue } from '@tldraw/editor'
|
|
10
2
|
import { supportsDownloadingOriginal } from '../context/actions'
|
|
11
3
|
import { useUiEvents } from '../context/events'
|
|
12
4
|
import { useToasts } from '../context/toasts'
|
|
@@ -64,7 +56,7 @@ export function FlattenMenuItem() {
|
|
|
64
56
|
const selectedShapeIds = editor.getSelectedShapeIds()
|
|
65
57
|
if (selectedShapeIds.length === 0) return false
|
|
66
58
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
67
|
-
if (onlySelectedShape && editor.isShapeOfType
|
|
59
|
+
if (onlySelectedShape && editor.isShapeOfType(onlySelectedShape, 'image')) {
|
|
68
60
|
return false
|
|
69
61
|
}
|
|
70
62
|
return true
|
|
@@ -117,7 +109,7 @@ export function RemoveFrameMenuItem() {
|
|
|
117
109
|
() => {
|
|
118
110
|
const selectedShapes = editor.getSelectedShapes()
|
|
119
111
|
if (selectedShapes.length === 0) return false
|
|
120
|
-
return selectedShapes.every((shape) => editor.isShapeOfType
|
|
112
|
+
return selectedShapes.every((shape) => editor.isShapeOfType(shape, 'frame'))
|
|
121
113
|
},
|
|
122
114
|
[editor]
|
|
123
115
|
)
|
|
@@ -135,7 +127,7 @@ export function FitFrameToContentMenuItem() {
|
|
|
135
127
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
136
128
|
if (!onlySelectedShape) return false
|
|
137
129
|
return (
|
|
138
|
-
editor.isShapeOfType
|
|
130
|
+
editor.isShapeOfType(onlySelectedShape, 'frame') &&
|
|
139
131
|
editor.getSortedChildIdsForParent(onlySelectedShape).length > 0
|
|
140
132
|
)
|
|
141
133
|
},
|
|
@@ -518,7 +510,7 @@ export function ConvertToBookmarkMenuItem() {
|
|
|
518
510
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
519
511
|
if (!onlySelectedShape) return false
|
|
520
512
|
return !!(
|
|
521
|
-
editor.isShapeOfType
|
|
513
|
+
editor.isShapeOfType(onlySelectedShape, 'embed') &&
|
|
522
514
|
onlySelectedShape.props.url &&
|
|
523
515
|
!editor.isShapeOrAncestorLocked(onlySelectedShape)
|
|
524
516
|
)
|
|
@@ -542,7 +534,7 @@ export function ConvertToEmbedMenuItem() {
|
|
|
542
534
|
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
543
535
|
if (!onlySelectedShape) return false
|
|
544
536
|
return !!(
|
|
545
|
-
editor.isShapeOfType
|
|
537
|
+
editor.isShapeOfType(onlySelectedShape, 'bookmark') &&
|
|
546
538
|
onlySelectedShape.props.url &&
|
|
547
539
|
getEmbedDefinition(onlySelectedShape.props.url) &&
|
|
548
540
|
!editor.isShapeOrAncestorLocked(onlySelectedShape)
|
|
@@ -6,6 +6,7 @@ export interface TLUiButtonProps extends React.HTMLAttributes<HTMLButtonElement>
|
|
|
6
6
|
disabled?: boolean
|
|
7
7
|
isActive?: boolean
|
|
8
8
|
type: 'normal' | 'primary' | 'danger' | 'low' | 'icon' | 'tool' | 'menu' | 'help'
|
|
9
|
+
htmlButtonType?: 'button' | 'submit' | 'reset'
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
const namedClassNamesSoThatICanGrepForThis = {
|
|
@@ -21,11 +22,11 @@ const namedClassNamesSoThatICanGrepForThis = {
|
|
|
21
22
|
|
|
22
23
|
/** @public @react */
|
|
23
24
|
export const TldrawUiButton = React.forwardRef<HTMLButtonElement, TLUiButtonProps>(
|
|
24
|
-
function TldrawUiButton({ children, type, isActive, ...props }, ref) {
|
|
25
|
+
function TldrawUiButton({ children, type, htmlButtonType, isActive, ...props }, ref) {
|
|
25
26
|
return (
|
|
26
27
|
<button
|
|
27
28
|
ref={ref}
|
|
28
|
-
type=
|
|
29
|
+
type={htmlButtonType || 'button'}
|
|
29
30
|
draggable={false}
|
|
30
31
|
data-isactive={isActive}
|
|
31
32
|
{...props}
|
|
@@ -134,6 +134,7 @@ export function TldrawUiMenuItem<
|
|
|
134
134
|
{iconLeft && <TldrawUiButtonIcon icon={iconLeft} small />}
|
|
135
135
|
<TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>
|
|
136
136
|
{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}
|
|
137
|
+
{icon && <TldrawUiButtonIcon icon={icon} small />}
|
|
137
138
|
</TldrawUiButton>
|
|
138
139
|
</TldrawUiDropdownMenuItem>
|
|
139
140
|
)
|