tldraw 5.2.0-next.e2b8d10bf10e → 5.2.0
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/DOCS.md +20294 -0
- package/README.md +13 -1
- package/RELEASE_NOTES.md +2908 -0
- package/dist-cjs/index.d.ts +110 -23
- package/dist-cjs/index.js +3 -3
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawImage.js +0 -1
- package/dist-cjs/lib/TldrawImage.js.map +2 -2
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
- package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
- package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
- package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
- package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
- package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
- package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/HandTool.js +16 -6
- package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +12 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +4 -3
- package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +2 -0
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +7 -0
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +70 -1
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
- package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
- 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 +2 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.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/embeds/embeds.js +4 -4
- package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
- package/dist-cjs/lib/utils/test-helpers.js +2 -2
- package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
- package/dist-cjs/lib/utils/text/richText.js +3 -1
- package/dist-cjs/lib/utils/text/richText.js.map +2 -2
- package/dist-esm/index.d.mts +110 -23
- package/dist-esm/index.mjs +5 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawImage.mjs +0 -1
- package/dist-esm/lib/TldrawImage.mjs.map +2 -2
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
- package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
- package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
- package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
- package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/HandTool.mjs +16 -6
- package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +12 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -0
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
- package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +2 -0
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +71 -1
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
- package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.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/embeds/embeds.mjs +4 -4
- package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
- package/dist-esm/lib/utils/text/richText.mjs +3 -1
- package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
- package/package.json +11 -6
- package/src/index.ts +6 -1
- package/src/lib/TldrawImage.tsx +2 -2
- package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
- package/src/lib/defaultEmbedDefinitions.ts +28 -6
- package/src/lib/defaultOverlayUtils.ts +11 -11
- package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
- package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
- package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
- package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
- package/src/lib/shapes/draw/getPath.ts +1 -1
- package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
- package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
- package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
- package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
- package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
- package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
- package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
- package/src/lib/shapes/note/noteCloning.test.ts +5 -5
- package/src/lib/shapes/note/noteHelpers.ts +1 -1
- package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
- package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
- package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
- package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
- package/src/lib/shapes/shared/freehand/core.ts +547 -0
- package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
- package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
- package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
- package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
- package/src/lib/shapes/shared/freehand/svg.ts +72 -23
- package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
- package/src/lib/shapes/shared/freehand/types.ts +0 -1
- package/src/lib/shapes/shared/interpolate-props.ts +6 -2
- package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
- package/src/lib/tools/HandTool/HandTool.ts +19 -6
- package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
- package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
- package/src/lib/tools/SelectTool/childStates/Idle.ts +16 -2
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +8 -0
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
- package/src/lib/ui/TldrawUi.tsx +3 -3
- package/src/lib/ui/components/A11y.tsx +2 -0
- package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
- package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
- package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
- package/src/lib/ui/components/Dialogs.tsx +20 -23
- package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
- package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
- package/src/lib/ui/components/menu-items.tsx +9 -0
- package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
- package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
- package/src/lib/ui/context/actions.tsx +88 -1
- package/src/lib/ui/context/asset-urls.tsx +9 -8
- package/src/lib/ui/context/events.tsx +2 -0
- package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
- package/src/lib/ui/hooks/useTools.tsx +7 -1
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +20 -9
- package/src/lib/utils/embeds/embeds.test.ts +14 -12
- package/src/lib/utils/embeds/embeds.ts +10 -4
- package/src/lib/utils/test-helpers.ts +3 -3
- package/src/lib/utils/text/richText.test.ts +36 -0
- package/src/lib/utils/text/richText.ts +9 -1
- package/src/test/HandTool.test.ts +93 -0
- package/src/test/ImageShapeUtil.test.ts +88 -0
- package/src/test/SelectTool.test.ts +102 -1
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
- package/src/test/attribution.test.ts +40 -29
- package/src/test/bookmark-shapes.test.ts +256 -28
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
- package/src/test/commands/clipboardCallbacks.test.ts +3 -1
- package/src/test/commands/getSvgString.test.ts +30 -0
- package/src/test/commands/penmode.test.ts +97 -1
- package/src/test/commands/setCamera.test.ts +12 -0
- package/src/test/dragFromToolbar.test.ts +67 -0
- package/src/test/drawing.test.ts +48 -7
- package/src/test/frames.test.ts +72 -0
- package/src/test/freehand/corpus/presets.ts +71 -0
- package/src/test/freehand/corpus/real.ts +370 -0
- package/src/test/freehand/corpus/strokes.ts +50 -0
- package/src/test/freehand/svg.test.ts +20 -0
- package/src/test/freehand/wellformed.test.ts +30 -0
- package/src/test/long-press-create.test.ts +102 -0
- package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
- package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
- package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
- package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
- package/src/test/overlays/OverlayManager.test.ts +1 -1
- package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
- package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
- package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
- package/src/test/resizing.test.ts +250 -0
- package/src/test/right-click-context-menu.test.ts +90 -0
- package/src/test/rightClickPanning.test.ts +11 -0
- package/src/test/selection-omnibus.test.ts +15 -2
- package/src/test/spatialIndex.test.ts +132 -0
- package/src/test/translating.test.ts +0 -6
- package/src/test/ui/ContextMenu.test.tsx +146 -3
- package/src/test/ui/Dialogs.test.tsx +256 -0
- package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
- package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
- package/tldraw.css +35 -12
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
- package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
TLAssetId,
|
|
6
6
|
TLBookmarkAsset,
|
|
7
7
|
TLBookmarkShape,
|
|
8
|
+
TLShapeId,
|
|
8
9
|
TLShapePartial,
|
|
9
10
|
createShapeId,
|
|
10
11
|
debounce,
|
|
@@ -84,6 +85,44 @@ export function updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmark
|
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the asset id to render for a bookmark. Bookmark assets are keyed
|
|
90
|
+
* deterministically by URL, so if the shape has no `assetId` but an asset for
|
|
91
|
+
* its URL already exists in the store, use that.
|
|
92
|
+
*
|
|
93
|
+
* This keeps a bookmark from staying stuck on its placeholder after the shape
|
|
94
|
+
* is recreated outside of the hydration flow — e.g. on redo, where the
|
|
95
|
+
* placeholder is restored with a null `assetId` but its hydrated asset (created
|
|
96
|
+
* with `history: 'ignore'`) still lives in the store.
|
|
97
|
+
*/
|
|
98
|
+
export function getResolvedBookmarkAssetId(
|
|
99
|
+
editor: Editor,
|
|
100
|
+
assetId: TLAssetId | null,
|
|
101
|
+
url: string
|
|
102
|
+
): TLAssetId | null {
|
|
103
|
+
if (assetId) return assetId
|
|
104
|
+
if (!url) return null
|
|
105
|
+
|
|
106
|
+
const derivedId: TLAssetId = AssetRecordType.createId(getHashForString(url))
|
|
107
|
+
return editor.getAsset(derivedId) ? derivedId : null
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The effective height to render and measure a bookmark at.
|
|
112
|
+
*
|
|
113
|
+
* Normally this is the stored `props.h`. But when the shape's `assetId` resolves
|
|
114
|
+
* to a different asset than it stores — e.g. a placeholder restored on redo with
|
|
115
|
+
* a null `assetId` whose asset already exists in the store — `props.h` is stale
|
|
116
|
+
* (it still holds the placeholder height). In that case recompute the height
|
|
117
|
+
* from the resolved asset so rendering, the indicator, and the geometry/selection
|
|
118
|
+
* bounds all stay in sync.
|
|
119
|
+
*/
|
|
120
|
+
export function getBookmarkShapeHeight(editor: Editor, shape: TLBookmarkShape): number {
|
|
121
|
+
const resolvedAssetId = getResolvedBookmarkAssetId(editor, shape.props.assetId, shape.props.url)
|
|
122
|
+
if (resolvedAssetId === shape.props.assetId) return shape.props.h
|
|
123
|
+
return getBookmarkHeight(editor, resolvedAssetId)
|
|
124
|
+
}
|
|
125
|
+
|
|
87
126
|
async function _createBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape) {
|
|
88
127
|
if (editor.isDisposed) return
|
|
89
128
|
|
|
@@ -128,12 +167,17 @@ function createBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape)
|
|
|
128
167
|
}
|
|
129
168
|
|
|
130
169
|
/**
|
|
131
|
-
* Creates a bookmark shape from a URL
|
|
170
|
+
* Creates a bookmark shape from a URL.
|
|
171
|
+
*
|
|
172
|
+
* The shape is created immediately as a placeholder so the user gets visible
|
|
173
|
+
* feedback at the paste location, and the bookmark metadata (title, description,
|
|
174
|
+
* image, favicon) is fetched in the background. Once metadata resolves, the
|
|
175
|
+
* shape is patched with the resulting asset. If the fetch fails, the shape is
|
|
176
|
+
* left as a URL-only bookmark.
|
|
132
177
|
*
|
|
133
178
|
* @returns A Result containing the created bookmark shape or an error
|
|
134
179
|
* @public
|
|
135
180
|
*/
|
|
136
|
-
|
|
137
181
|
export async function createBookmarkFromUrl(
|
|
138
182
|
editor: Editor,
|
|
139
183
|
{
|
|
@@ -145,10 +189,12 @@ export async function createBookmarkFromUrl(
|
|
|
145
189
|
}
|
|
146
190
|
): Promise<Result<TLBookmarkShape, string>> {
|
|
147
191
|
try {
|
|
148
|
-
//
|
|
149
|
-
|
|
192
|
+
// If we already have a bookmark asset for this URL (e.g. another bookmark
|
|
193
|
+
// shape was created from the same URL earlier), use it immediately rather
|
|
194
|
+
// than re-fetching.
|
|
195
|
+
const expectedAssetId: TLAssetId = AssetRecordType.createId(getHashForString(url))
|
|
196
|
+
const existingAsset = editor.getAsset(expectedAssetId) as TLBookmarkAsset | null
|
|
150
197
|
|
|
151
|
-
// Create the bookmark shape
|
|
152
198
|
const shapeId = createShapeId()
|
|
153
199
|
const shapePartial: TLShapePartial<TLBookmarkShape> = {
|
|
154
200
|
id: shapeId,
|
|
@@ -159,26 +205,70 @@ export async function createBookmarkFromUrl(
|
|
|
159
205
|
opacity: 1,
|
|
160
206
|
props: {
|
|
161
207
|
url,
|
|
162
|
-
assetId:
|
|
208
|
+
assetId: existingAsset?.id ?? null,
|
|
163
209
|
w: BOOKMARK_WIDTH,
|
|
164
|
-
h: getBookmarkHeight(editor,
|
|
210
|
+
h: getBookmarkHeight(editor, existingAsset?.id),
|
|
165
211
|
},
|
|
166
212
|
}
|
|
167
213
|
|
|
168
214
|
editor.run(() => {
|
|
169
|
-
// Create the asset if we have one
|
|
170
|
-
if (asset) {
|
|
171
|
-
editor.createAssets([asset])
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Create the shape
|
|
175
215
|
editor.createShapes([shapePartial])
|
|
176
216
|
})
|
|
177
217
|
|
|
178
|
-
|
|
179
|
-
|
|
218
|
+
const createdShape = editor.getShape<TLBookmarkShape>(shapeId)
|
|
219
|
+
if (!createdShape) {
|
|
220
|
+
return Result.err('Failed to create bookmark shape')
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// If we already had the asset, we're done — no metadata fetch needed.
|
|
224
|
+
if (existingAsset) {
|
|
225
|
+
return Result.ok(createdShape)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Otherwise kick off the metadata fetch in the background. The shape is
|
|
229
|
+
// already visible as a placeholder; once the asset resolves we'll patch
|
|
230
|
+
// the shape with its assetId.
|
|
231
|
+
void hydrateBookmarkShape(editor, shapeId, url)
|
|
232
|
+
|
|
180
233
|
return Result.ok(createdShape)
|
|
181
234
|
} catch (error) {
|
|
182
235
|
return Result.err(error instanceof Error ? error.message : 'Failed to create bookmark')
|
|
183
236
|
}
|
|
184
237
|
}
|
|
238
|
+
|
|
239
|
+
async function hydrateBookmarkShape(editor: Editor, shapeId: TLShapeId, url: string) {
|
|
240
|
+
let asset
|
|
241
|
+
try {
|
|
242
|
+
asset = await editor.getAssetForExternalContent({ type: 'url', url })
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error(error)
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (editor.isDisposed) return
|
|
249
|
+
if (!asset) return
|
|
250
|
+
|
|
251
|
+
// The shape may have been deleted (e.g. via undo), had its URL changed, or
|
|
252
|
+
// had its asset replaced before the fetch resolved. In any of those cases we
|
|
253
|
+
// don't want to attach metadata for the old URL.
|
|
254
|
+
const shape = editor.getShape<TLBookmarkShape>(shapeId)
|
|
255
|
+
if (!shape) return
|
|
256
|
+
if (shape.props.url !== url) return
|
|
257
|
+
if (shape.props.assetId) return
|
|
258
|
+
|
|
259
|
+
editor.run(
|
|
260
|
+
() => {
|
|
261
|
+
if (!editor.getAsset(asset.id)) {
|
|
262
|
+
editor.createAssets([asset])
|
|
263
|
+
}
|
|
264
|
+
editor.updateShapes([
|
|
265
|
+
{
|
|
266
|
+
id: shapeId,
|
|
267
|
+
type: 'bookmark',
|
|
268
|
+
props: { assetId: asset.id },
|
|
269
|
+
},
|
|
270
|
+
])
|
|
271
|
+
},
|
|
272
|
+
{ history: 'ignore' }
|
|
273
|
+
)
|
|
274
|
+
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
TLResizeInfo,
|
|
12
12
|
TLShapeUtilCanvasSvgDef,
|
|
13
13
|
VecLike,
|
|
14
|
+
b64Vecs,
|
|
14
15
|
drawShapeMigrations,
|
|
15
16
|
drawShapeProps,
|
|
16
17
|
getColorValue,
|
|
@@ -266,11 +267,12 @@ function getDot(point: VecLike, sw: number) {
|
|
|
266
267
|
}
|
|
267
268
|
|
|
268
269
|
function getIsDot(shape: TLDrawShape) {
|
|
269
|
-
//
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
|
|
270
|
+
// A dot is a single-point segment. isSinglePoint knows the per-encoding length
|
|
271
|
+
// (and takes the segment's dim), so this stays correct for both 2D and 3D paths.
|
|
272
|
+
// A bare length threshold can't: a 2-point 2D path is the same length as a 1-point
|
|
273
|
+
// 3D path, so only the dim disambiguates them.
|
|
274
|
+
const segment = shape.props.segments[0]
|
|
275
|
+
return shape.props.segments.length === 1 && b64Vecs.isSinglePoint(segment.path, segment.dim)
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
function DrawShapeSvg({
|
|
@@ -109,7 +109,7 @@ export function getPointsFromDrawSegment(
|
|
|
109
109
|
scaleY: number,
|
|
110
110
|
points: Vec[] = []
|
|
111
111
|
) {
|
|
112
|
-
const _points = b64Vecs.decodePoints(segment.path)
|
|
112
|
+
const _points = b64Vecs.decodePoints(segment.path, segment.dim)
|
|
113
113
|
|
|
114
114
|
// Apply scale factors (used for lazy resize and flipping)
|
|
115
115
|
if (scaleX !== 1 || scaleY !== 1) {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
TLKeyboardEventInfo,
|
|
9
9
|
TLPointerEventInfo,
|
|
10
10
|
TLShapePartial,
|
|
11
|
+
DIM_2D,
|
|
11
12
|
Vec,
|
|
12
13
|
VecModel,
|
|
13
14
|
b64Vecs,
|
|
@@ -40,6 +41,11 @@ export class Drawing extends StateNode {
|
|
|
40
41
|
isPen = false
|
|
41
42
|
isPenOrStylus = false
|
|
42
43
|
|
|
44
|
+
// Encoding dimension for segments created during this stroke. `2` drops the
|
|
45
|
+
// constant pressure value (non-pressure devices), `undefined` keeps full 3D.
|
|
46
|
+
// Decided once in startShape from the input device — see the note there.
|
|
47
|
+
segmentDim: 2 | undefined = undefined
|
|
48
|
+
|
|
43
49
|
segmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'
|
|
44
50
|
|
|
45
51
|
didJustShiftClickToExtendPreviousShapeLine = false
|
|
@@ -157,9 +163,9 @@ export class Drawing extends StateNode {
|
|
|
157
163
|
const theme = this.editor.getCurrentTheme()
|
|
158
164
|
strokeWidth = theme.strokeWidth * STROKE_SIZES[size]
|
|
159
165
|
}
|
|
160
|
-
const firstPoint = b64Vecs.decodeFirstPoint(segments[0].path)
|
|
166
|
+
const firstPoint = b64Vecs.decodeFirstPoint(segments[0].path, segments[0].dim)
|
|
161
167
|
const lastSegment = segments[segments.length - 1]
|
|
162
|
-
const lastPoint = b64Vecs.decodeLastPoint(lastSegment.path)
|
|
168
|
+
const lastPoint = b64Vecs.decodeLastPoint(lastSegment.path, lastSegment.dim)
|
|
163
169
|
|
|
164
170
|
const isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode()
|
|
165
171
|
|
|
@@ -180,6 +186,16 @@ export class Drawing extends StateNode {
|
|
|
180
186
|
)
|
|
181
187
|
}
|
|
182
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Build a segment from points, encoding `path` at this stroke's `segmentDim` and
|
|
191
|
+
* attaching `dim: 2` only when z was dropped. 3D segments omit `dim` so they
|
|
192
|
+
* serialize byte-identically to pre-#8879 data.
|
|
193
|
+
*/
|
|
194
|
+
private makeSegment(type: TLDrawShapeSegment['type'], points: VecModel[]): TLDrawShapeSegment {
|
|
195
|
+
const path = b64Vecs.encodePoints(points, this.segmentDim)
|
|
196
|
+
return this.segmentDim === DIM_2D ? { type, path, dim: DIM_2D } : { type, path }
|
|
197
|
+
}
|
|
198
|
+
|
|
183
199
|
private startShape() {
|
|
184
200
|
const inputs = this.editor.inputs
|
|
185
201
|
const originPagePoint = inputs.getOriginPagePoint()
|
|
@@ -199,6 +215,13 @@ export class Drawing extends StateNode {
|
|
|
199
215
|
// or a broken OS.
|
|
200
216
|
this.isPenOrStylus = (isPen && z !== 0) || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)
|
|
201
217
|
|
|
218
|
+
// Decide the encoding dimension once, here, from the input device — not by
|
|
219
|
+
// scanning point data (content-driven). Device-driven keeps the encoded bytes
|
|
220
|
+
// deterministic and is O(1) at stroke start. Non-pressure devices report a
|
|
221
|
+
// constant z (0 / 0.5 / 1) that we normalize to 0.5 and omit entirely (2D);
|
|
222
|
+
// pen/stylus input keeps the full 3D encoding.
|
|
223
|
+
this.segmentDim = this.isPenOrStylus ? undefined : DIM_2D
|
|
224
|
+
|
|
202
225
|
const pressure = this.isPenOrStylus ? z * 1.25 : 0.5
|
|
203
226
|
|
|
204
227
|
this.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'
|
|
@@ -217,18 +240,15 @@ export class Drawing extends StateNode {
|
|
|
217
240
|
|
|
218
241
|
const prevSegment = last(shape.props.segments)
|
|
219
242
|
if (!prevSegment) throw Error('Expected a previous segment!')
|
|
220
|
-
const prevPoint = b64Vecs.decodeLastPoint(prevSegment.path)
|
|
243
|
+
const prevPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)
|
|
221
244
|
if (!prevPoint) throw Error('Expected a previous point!')
|
|
222
245
|
|
|
223
246
|
const { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()
|
|
224
247
|
|
|
225
|
-
const newSegment
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
{ x, y, z: +pressure.toFixed(2) },
|
|
230
|
-
]),
|
|
231
|
-
}
|
|
248
|
+
const newSegment = this.makeSegment(this.segmentMode, [
|
|
249
|
+
{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },
|
|
250
|
+
{ x, y, z: +pressure.toFixed(2) },
|
|
251
|
+
])
|
|
232
252
|
|
|
233
253
|
// Convert prevPoint to page space
|
|
234
254
|
const prevPointPageSpace = Mat.applyToPoint(
|
|
@@ -285,12 +305,7 @@ export class Drawing extends StateNode {
|
|
|
285
305
|
props: {
|
|
286
306
|
isPen: this.isPenOrStylus,
|
|
287
307
|
scale: this.editor.getResizeScaleFactor(),
|
|
288
|
-
segments: [
|
|
289
|
-
{
|
|
290
|
-
type: this.segmentMode,
|
|
291
|
-
path: b64Vecs.encodePoints([initialPoint]),
|
|
292
|
-
},
|
|
293
|
-
],
|
|
308
|
+
segments: [this.makeSegment(this.segmentMode, [initialPoint])],
|
|
294
309
|
},
|
|
295
310
|
})
|
|
296
311
|
const shape = this.editor.getShape<DrawableShape>(id)
|
|
@@ -350,7 +365,7 @@ export class Drawing extends StateNode {
|
|
|
350
365
|
const prevSegment = last(segments)
|
|
351
366
|
if (!prevSegment) throw Error('Expected a previous segment!')
|
|
352
367
|
|
|
353
|
-
const prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path)
|
|
368
|
+
const prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)
|
|
354
369
|
if (!prevLastPoint) throw Error('Expected a previous last point!')
|
|
355
370
|
|
|
356
371
|
let newSegment: TLDrawShapeSegment
|
|
@@ -363,19 +378,13 @@ export class Drawing extends StateNode {
|
|
|
363
378
|
if (prevSegment.type === 'straight') {
|
|
364
379
|
this.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)
|
|
365
380
|
|
|
366
|
-
newSegment =
|
|
367
|
-
type: 'straight',
|
|
368
|
-
path: b64Vecs.encodePoints([prevLastPoint, newLastPoint]),
|
|
369
|
-
}
|
|
381
|
+
newSegment = this.makeSegment('straight', [prevLastPoint, newLastPoint])
|
|
370
382
|
|
|
371
383
|
const transform = this.editor.getShapePageTransform(shape)!
|
|
372
384
|
|
|
373
385
|
this.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)
|
|
374
386
|
} else {
|
|
375
|
-
newSegment =
|
|
376
|
-
type: 'straight',
|
|
377
|
-
path: b64Vecs.encodePoints([newLastPoint, newPoint]),
|
|
378
|
-
}
|
|
387
|
+
newSegment = this.makeSegment('straight', [newLastPoint, newPoint])
|
|
379
388
|
}
|
|
380
389
|
|
|
381
390
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
|
@@ -422,7 +431,10 @@ export class Drawing extends StateNode {
|
|
|
422
431
|
|
|
423
432
|
const newSegments = segments.slice()
|
|
424
433
|
const prevStraightSegment = newSegments[newSegments.length - 1]
|
|
425
|
-
const prevPoint = b64Vecs.decodeLastPoint(
|
|
434
|
+
const prevPoint = b64Vecs.decodeLastPoint(
|
|
435
|
+
prevStraightSegment.path,
|
|
436
|
+
prevStraightSegment.dim
|
|
437
|
+
)
|
|
426
438
|
|
|
427
439
|
if (!prevPoint) {
|
|
428
440
|
throw Error('No previous point!')
|
|
@@ -436,10 +448,7 @@ export class Drawing extends StateNode {
|
|
|
436
448
|
// Initialize cache for the new free segment
|
|
437
449
|
this.currentSegmentPoints = interpolatedPoints
|
|
438
450
|
|
|
439
|
-
const newFreeSegment
|
|
440
|
-
type: 'free',
|
|
441
|
-
path: b64Vecs.encodePoints(interpolatedPoints),
|
|
442
|
-
}
|
|
451
|
+
const newFreeSegment = this.makeSegment('free', interpolatedPoints)
|
|
443
452
|
|
|
444
453
|
const finalSegments = [...newSegments, newFreeSegment]
|
|
445
454
|
|
|
@@ -516,8 +525,8 @@ export class Drawing extends StateNode {
|
|
|
516
525
|
if (!segment) break
|
|
517
526
|
if (segment.type === 'free') continue
|
|
518
527
|
|
|
519
|
-
const first = b64Vecs.decodeFirstPoint(segment.path)
|
|
520
|
-
const lastPoint = b64Vecs.decodeLastPoint(segment.path)
|
|
528
|
+
const first = b64Vecs.decodeFirstPoint(segment.path, segment.dim)
|
|
529
|
+
const lastPoint = b64Vecs.decodeLastPoint(segment.path, segment.dim)
|
|
521
530
|
if (!(first && lastPoint)) continue
|
|
522
531
|
|
|
523
532
|
// Snap to the nearest point on the segment, if it's closer than the previous snapped point
|
|
@@ -544,8 +553,8 @@ export class Drawing extends StateNode {
|
|
|
544
553
|
|
|
545
554
|
if (didSnap && snapSegment) {
|
|
546
555
|
const transform = this.editor.getShapePageTransform(shape)!
|
|
547
|
-
const first = b64Vecs.decodeFirstPoint(snapSegment.path)
|
|
548
|
-
const lastPoint = b64Vecs.decodeLastPoint(snapSegment.path)
|
|
556
|
+
const first = b64Vecs.decodeFirstPoint(snapSegment.path, snapSegment.dim)
|
|
557
|
+
const lastPoint = b64Vecs.decodeLastPoint(snapSegment.path, snapSegment.dim)
|
|
549
558
|
if (!first || !lastPoint) throw Error('Expected a last point!')
|
|
550
559
|
|
|
551
560
|
const A = Mat.applyToPoint(transform, first)
|
|
@@ -587,17 +596,20 @@ export class Drawing extends StateNode {
|
|
|
587
596
|
// without continuing the previous line. In this case, we want to remove the previous segment.
|
|
588
597
|
|
|
589
598
|
this.currentLineLength +=
|
|
590
|
-
newSegments.length && b64Vecs.decodeFirstPoint(newSegment.path)
|
|
591
|
-
? Vec.Dist(
|
|
599
|
+
newSegments.length && b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)
|
|
600
|
+
? Vec.Dist(
|
|
601
|
+
b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!,
|
|
602
|
+
Vec.From(newPoint)
|
|
603
|
+
)
|
|
592
604
|
: 0
|
|
593
605
|
|
|
594
606
|
newSegments[newSegments.length - 1] = {
|
|
595
607
|
...newSegment,
|
|
596
608
|
type: 'straight',
|
|
597
|
-
path: b64Vecs.encodePoints(
|
|
598
|
-
b64Vecs.decodeFirstPoint(newSegment.path)!,
|
|
599
|
-
|
|
600
|
-
|
|
609
|
+
path: b64Vecs.encodePoints(
|
|
610
|
+
[b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!, Vec.From(newPoint)],
|
|
611
|
+
newSegment.dim
|
|
612
|
+
),
|
|
601
613
|
}
|
|
602
614
|
|
|
603
615
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
|
@@ -642,7 +654,7 @@ export class Drawing extends StateNode {
|
|
|
642
654
|
const newSegment = newSegments[newSegments.length - 1]
|
|
643
655
|
newSegments[newSegments.length - 1] = {
|
|
644
656
|
...newSegment,
|
|
645
|
-
path: b64Vecs.encodePoints(cachedPoints),
|
|
657
|
+
path: b64Vecs.encodePoints(cachedPoints, newSegment.dim),
|
|
646
658
|
}
|
|
647
659
|
|
|
648
660
|
const dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })
|
|
@@ -692,12 +704,7 @@ export class Drawing extends StateNode {
|
|
|
692
704
|
props: {
|
|
693
705
|
isPen: this.isPenOrStylus,
|
|
694
706
|
scale: props.scale,
|
|
695
|
-
segments: [
|
|
696
|
-
{
|
|
697
|
-
type: 'free',
|
|
698
|
-
path: b64Vecs.encodePoints([initialPoint]),
|
|
699
|
-
},
|
|
700
|
-
],
|
|
707
|
+
segments: [this.makeSegment('free', [initialPoint])],
|
|
701
708
|
},
|
|
702
709
|
})
|
|
703
710
|
|
|
@@ -724,7 +731,7 @@ export class Drawing extends StateNode {
|
|
|
724
731
|
let length = 0
|
|
725
732
|
|
|
726
733
|
for (let j = 0; j < segments.length; j++) {
|
|
727
|
-
const points = b64Vecs.decodePoints(segments[j].path)
|
|
734
|
+
const points = b64Vecs.decodePoints(segments[j].path, segments[j].dim)
|
|
728
735
|
for (let i = 0; i < points.length - 1; i++) {
|
|
729
736
|
length += Vec.Dist2(points[i], points[i + 1])
|
|
730
737
|
}
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from '@tldraw/editor'
|
|
19
19
|
import {
|
|
20
20
|
DEFAULT_EMBED_DEFINITIONS,
|
|
21
|
-
|
|
21
|
+
DefaultEmbedConfig,
|
|
22
22
|
TLEmbedDefinition,
|
|
23
23
|
TLEmbedShapePermissions,
|
|
24
24
|
embedShapePermissionDefaults,
|
|
@@ -41,6 +41,15 @@ export interface EmbedShapeOptions extends ShapeOptionsWithDisplayValues<
|
|
|
41
41
|
> {
|
|
42
42
|
/** The embed definitions to use for this shape util. */
|
|
43
43
|
readonly embedDefinitions: readonly TLEmbedDefinition[]
|
|
44
|
+
/**
|
|
45
|
+
* Per-embed configuration, keyed by embed type. Passed to each definition's `toEmbedUrl` when
|
|
46
|
+
* building its embed URL — for example, an API key for the default Google Maps embed:
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* EmbedShapeUtil.configure({ embedConfig: { google_maps: { apiKey: '...' } } })
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
readonly embedConfig?: DefaultEmbedConfig & Record<string, unknown>
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
const getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {
|
|
@@ -58,6 +67,7 @@ export class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {
|
|
|
58
67
|
|
|
59
68
|
override options: EmbedShapeOptions = {
|
|
60
69
|
embedDefinitions: DEFAULT_EMBED_DEFINITIONS,
|
|
70
|
+
embedConfig: {},
|
|
61
71
|
getDefaultDisplayValues(): EmbedShapeUtilDisplayValues {
|
|
62
72
|
return {
|
|
63
73
|
showShadow: true,
|
|
@@ -74,10 +84,10 @@ export class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {
|
|
|
74
84
|
return result.definition.canEditWhileLocked ?? true
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
private static legacyEmbedDefinitions: readonly
|
|
87
|
+
private static legacyEmbedDefinitions: readonly TLEmbedDefinition[] | null = null
|
|
78
88
|
|
|
79
89
|
/** @deprecated - Use `EmbedShapeUtil.configure({ embedDefinitions: [...] })` instead. */
|
|
80
|
-
static setEmbedDefinitions(embedDefinitions: readonly
|
|
90
|
+
static setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {
|
|
81
91
|
EmbedShapeUtil.legacyEmbedDefinitions = embedDefinitions
|
|
82
92
|
}
|
|
83
93
|
|
|
@@ -90,7 +100,7 @@ export class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {
|
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
getEmbedDefinition(url: string): TLEmbedResult {
|
|
93
|
-
return getEmbedInfo(this.getEmbedDefs(), url)
|
|
103
|
+
return getEmbedInfo(this.getEmbedDefs(), url, this.options.embedConfig)
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
override getText(shape: TLEmbedShape) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseBoxShapeTool, TLShape, TLShapeId } from '@tldraw/editor'
|
|
1
|
+
import { BaseBoxShapeTool, Editor, TLShape, TLShapeId } from '@tldraw/editor'
|
|
2
2
|
|
|
3
3
|
/** @public */
|
|
4
4
|
export class FrameShapeTool extends BaseBoxShapeTool {
|
|
@@ -9,29 +9,7 @@ export class FrameShapeTool extends BaseBoxShapeTool {
|
|
|
9
9
|
override onCreate(shape: TLShape | null): void {
|
|
10
10
|
if (!shape) return
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
const shapesToAddToFrame: TLShapeId[] = []
|
|
14
|
-
const ancestorIds = this.editor.getShapeAncestors(shape).map((shape) => shape.id)
|
|
15
|
-
|
|
16
|
-
this.editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
|
|
17
|
-
const siblingShape = this.editor.getShape(siblingShapeId)
|
|
18
|
-
if (!siblingShape) return
|
|
19
|
-
// We don't want to frame the frame itself
|
|
20
|
-
if (siblingShape.id === shape.id) return
|
|
21
|
-
if (siblingShape.isLocked) return
|
|
22
|
-
|
|
23
|
-
const pageShapeBounds = this.editor.getShapePageBounds(siblingShape)
|
|
24
|
-
if (!pageShapeBounds) return
|
|
25
|
-
|
|
26
|
-
// Frame shape encloses page shape
|
|
27
|
-
if (bounds.contains(pageShapeBounds)) {
|
|
28
|
-
if (canEnclose(siblingShape, ancestorIds, shape)) {
|
|
29
|
-
shapesToAddToFrame.push(siblingShape.id)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
this.editor.reparentShapes(shapesToAddToFrame, shape.id)
|
|
12
|
+
this.editor.reparentShapes(getEnclosedShapeIds(this.editor, shape), shape.id)
|
|
35
13
|
|
|
36
14
|
if (this.editor.getInstanceState().isToolLocked) {
|
|
37
15
|
this.editor.setCurrentTool('frame')
|
|
@@ -41,6 +19,39 @@ export class FrameShapeTool extends BaseBoxShapeTool {
|
|
|
41
19
|
}
|
|
42
20
|
}
|
|
43
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Get the ids of the sibling shapes that a frame would enclose at its current page bounds.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export function getEnclosedShapeIds(editor: Editor, shape: TLShape): TLShapeId[] {
|
|
28
|
+
const bounds = editor.getShapePageBounds(shape)
|
|
29
|
+
if (!bounds) return []
|
|
30
|
+
|
|
31
|
+
const enclosedShapeIds: TLShapeId[] = []
|
|
32
|
+
const ancestorIds = editor.getShapeAncestors(shape).map((shape) => shape.id)
|
|
33
|
+
|
|
34
|
+
editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
|
|
35
|
+
const siblingShape = editor.getShape(siblingShapeId)
|
|
36
|
+
if (!siblingShape) return
|
|
37
|
+
// We don't want to frame the frame itself
|
|
38
|
+
if (siblingShape.id === shape.id) return
|
|
39
|
+
if (siblingShape.isLocked) return
|
|
40
|
+
|
|
41
|
+
const pageShapeBounds = editor.getShapePageBounds(siblingShape)
|
|
42
|
+
if (!pageShapeBounds) return
|
|
43
|
+
|
|
44
|
+
// Frame shape encloses page shape
|
|
45
|
+
if (bounds.contains(pageShapeBounds)) {
|
|
46
|
+
if (canEnclose(siblingShape, ancestorIds, shape)) {
|
|
47
|
+
enclosedShapeIds.push(siblingShape.id)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return enclosedShapeIds
|
|
53
|
+
}
|
|
54
|
+
|
|
44
55
|
/** @internal */
|
|
45
56
|
function canEnclose(shape: TLShape, ancestorIds: TLShapeId[], frame: TLShape): boolean {
|
|
46
57
|
// We don't want to pull in shapes that are ancestors of the frame (can create a cycle)
|
|
@@ -182,6 +182,52 @@ describe('Resizing geo shapes with labels', () => {
|
|
|
182
182
|
})
|
|
183
183
|
})
|
|
184
184
|
|
|
185
|
+
describe('Geo shapes with programmatically-authored empty rich text', () => {
|
|
186
|
+
const geoId = createShapeId('geo')
|
|
187
|
+
|
|
188
|
+
function getGeo() {
|
|
189
|
+
return editor.getShape<TLGeoShape>(geoId)!
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// An empty paragraph can be encoded two equally-valid ways. The interactive
|
|
193
|
+
// editor emits the first (no `content` key); programmatic authoring (snapshot
|
|
194
|
+
// load, agents emitting tldraw JSON) commonly emits the second (`content: []`).
|
|
195
|
+
// Both mean "no label", so neither should grow the shape to fit a phantom line.
|
|
196
|
+
const emptyForms = [
|
|
197
|
+
{
|
|
198
|
+
label: 'paragraph with no content key (toRichText output)',
|
|
199
|
+
richText: toRichText(''),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: 'paragraph with empty content array',
|
|
203
|
+
richText: {
|
|
204
|
+
type: 'doc',
|
|
205
|
+
content: [{ type: 'paragraph', attrs: { dir: 'auto' }, content: [] }],
|
|
206
|
+
} as TLGeoShape['props']['richText'],
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
label: 'doc with empty content array',
|
|
210
|
+
richText: { type: 'doc', content: [] } as TLGeoShape['props']['richText'],
|
|
211
|
+
},
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
for (const { label, richText } of emptyForms) {
|
|
215
|
+
test(`does not grow height for an empty label: ${label}`, () => {
|
|
216
|
+
editor.createShapes([
|
|
217
|
+
{
|
|
218
|
+
id: geoId,
|
|
219
|
+
type: 'geo',
|
|
220
|
+
props: { w: 110, h: 24, geo: 'rectangle', size: 's', richText },
|
|
221
|
+
},
|
|
222
|
+
])
|
|
223
|
+
|
|
224
|
+
const geo = getGeo()
|
|
225
|
+
expect(geo.props.h).toBe(24)
|
|
226
|
+
expect(geo.props.growY).toBe(0)
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
|
|
185
231
|
describe('GeoShapeUtil.configure with customGeoTypes', () => {
|
|
186
232
|
// Snapshot the built-in geo values so we can clean up any custom keys added
|
|
187
233
|
// during these tests. `GeoShapeUtil.configure({ customGeoTypes })` mutates
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
getFontsFromRichText,
|
|
31
31
|
isEqual,
|
|
32
32
|
lerp,
|
|
33
|
+
resolveLineHeightPx,
|
|
33
34
|
toRichText,
|
|
34
35
|
useColorMode,
|
|
35
36
|
useValue,
|
|
@@ -271,7 +272,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
|
|
|
271
272
|
// Calculate minimum label dimensions based on font size and shape size
|
|
272
273
|
const unscaledMinWidth = Math.min(100, unscaledShapeW / 2)
|
|
273
274
|
const unscaledMinHeight = Math.min(
|
|
274
|
-
dv.labelFontSize
|
|
275
|
+
resolveLineHeightPx(dv.labelFontSize, dv.labelLineHeight) + dv.labelPadding * 2,
|
|
275
276
|
unscaledShapeH / 2
|
|
276
277
|
)
|
|
277
278
|
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
TLPointerEventInfo,
|
|
6
6
|
Vec,
|
|
7
7
|
createShapeId,
|
|
8
|
+
cancelShapeCreationOnLongPress,
|
|
8
9
|
maybeSnapToGrid,
|
|
9
10
|
} from '@tldraw/editor'
|
|
10
11
|
import { GeoShapeUtil } from '../GeoShapeUtil'
|
|
@@ -17,6 +18,10 @@ export class Pointing extends StateNode {
|
|
|
17
18
|
this.complete()
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
override onLongPress() {
|
|
22
|
+
cancelShapeCreationOnLongPress(this.editor, () => this.cancel())
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
override onPointerMove(info: TLPointerEventInfo) {
|
|
21
26
|
if (this.editor.inputs.getIsDragging()) {
|
|
22
27
|
const originPagePoint = this.editor.inputs.getOriginPagePoint()
|