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
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Box,
|
|
3
|
-
Circle2d,
|
|
4
3
|
Geometry2d,
|
|
5
4
|
HALF_PI,
|
|
6
5
|
Mat,
|
|
7
6
|
OverlayUtil,
|
|
8
7
|
Polygon2d,
|
|
8
|
+
Rectangle2d,
|
|
9
9
|
RotateCorner,
|
|
10
10
|
SelectionCorner,
|
|
11
11
|
SelectionEdge,
|
|
@@ -52,12 +52,17 @@ interface SelectionState {
|
|
|
52
52
|
rotation: number
|
|
53
53
|
width: number
|
|
54
54
|
height: number
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
/** Visual side length of the rendered resize-handle squares. */
|
|
56
|
+
handleSize: number
|
|
57
|
+
/** Base half-extent of the interactive hit target for handles. */
|
|
58
|
+
hitTargetSize: number
|
|
59
|
+
/** Hit target half-extent along the x axis (narrower for small selections). */
|
|
60
|
+
hitTargetSizeX: number
|
|
61
|
+
/** Hit target half-extent along the y axis (narrower for small selections). */
|
|
62
|
+
hitTargetSizeY: number
|
|
63
|
+
/** Offset from the unexpanded bounds to the expanded selection outline. */
|
|
64
|
+
expandOffsetX: number
|
|
65
|
+
expandOffsetY: number
|
|
61
66
|
isSmallX: boolean
|
|
62
67
|
shouldDisplayControls: boolean
|
|
63
68
|
shouldDisplayBox: boolean
|
|
@@ -97,6 +102,7 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
97
102
|
'select.pointing_selection',
|
|
98
103
|
'select.pointing_shape',
|
|
99
104
|
'select.pointing_resize_handle',
|
|
105
|
+
'select.pointing_rotate_handle',
|
|
100
106
|
'select.resizing',
|
|
101
107
|
'select.crop.idle',
|
|
102
108
|
'select.crop.pointing_crop',
|
|
@@ -122,7 +128,7 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
122
128
|
const transform = Mat.Compose(
|
|
123
129
|
Mat.Translate(state.bounds.x, state.bounds.y),
|
|
124
130
|
Mat.Rotate(state.rotation),
|
|
125
|
-
Mat.Translate(state.
|
|
131
|
+
Mat.Translate(state.expandOffsetX, state.expandOffsetY)
|
|
126
132
|
)
|
|
127
133
|
|
|
128
134
|
const { overlayType, handle } = overlay.props
|
|
@@ -147,7 +153,7 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
147
153
|
ctx.save()
|
|
148
154
|
ctx.translate(state.bounds.x, state.bounds.y)
|
|
149
155
|
ctx.rotate(state.rotation)
|
|
150
|
-
ctx.translate(state.
|
|
156
|
+
ctx.translate(state.expandOffsetX, state.expandOffsetY)
|
|
151
157
|
|
|
152
158
|
const colors = this._getThemeColors()
|
|
153
159
|
this._renderSelectionBox(ctx, state, colors)
|
|
@@ -253,12 +259,19 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
253
259
|
})
|
|
254
260
|
}
|
|
255
261
|
|
|
256
|
-
const
|
|
257
|
-
|
|
262
|
+
const cornerPoint = this._getCornerLocalPoint(
|
|
263
|
+
handle as SelectionCorner,
|
|
264
|
+
state.width,
|
|
265
|
+
state.height
|
|
266
|
+
)
|
|
267
|
+
const cornerHitHalfSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.5
|
|
258
268
|
return new Polygon2d({
|
|
259
|
-
points: this._localRectToPoints(
|
|
260
|
-
|
|
261
|
-
|
|
269
|
+
points: this._localRectToPoints(
|
|
270
|
+
cornerPoint.x - cornerHitHalfSize,
|
|
271
|
+
cornerPoint.y - cornerHitHalfSize,
|
|
272
|
+
cornerHitHalfSize * 2,
|
|
273
|
+
cornerHitHalfSize * 2
|
|
274
|
+
).map((p) => Mat.applyToPoint(transform, p)),
|
|
262
275
|
isFilled: true,
|
|
263
276
|
})
|
|
264
277
|
}
|
|
@@ -268,13 +281,14 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
268
281
|
state: SelectionState,
|
|
269
282
|
transform: Mat
|
|
270
283
|
): Geometry2d {
|
|
271
|
-
const cornerSize = Math.max(state.
|
|
284
|
+
const cornerSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.62
|
|
272
285
|
const center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize)
|
|
273
286
|
const radius = cornerSize
|
|
274
|
-
return new
|
|
287
|
+
return new Rectangle2d({
|
|
275
288
|
x: center.x - radius,
|
|
276
289
|
y: center.y - radius,
|
|
277
|
-
radius,
|
|
290
|
+
width: radius * 2,
|
|
291
|
+
height: radius * 2,
|
|
278
292
|
isFilled: true,
|
|
279
293
|
}).transform(transform)
|
|
280
294
|
}
|
|
@@ -310,7 +324,7 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
310
324
|
) {
|
|
311
325
|
if (!state.showResizeHandles) return
|
|
312
326
|
|
|
313
|
-
const {
|
|
327
|
+
const { handleSize, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state
|
|
314
328
|
|
|
315
329
|
ctx.fillStyle = colors.bgColor
|
|
316
330
|
ctx.strokeStyle = colors.strokeColor
|
|
@@ -318,8 +332,8 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
318
332
|
|
|
319
333
|
const drawCorner = (x: number, y: number, hidden: boolean) => {
|
|
320
334
|
if (hidden) return
|
|
321
|
-
ctx.fillRect(x -
|
|
322
|
-
ctx.strokeRect(x -
|
|
335
|
+
ctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)
|
|
336
|
+
ctx.strokeRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)
|
|
323
337
|
}
|
|
324
338
|
|
|
325
339
|
drawCorner(0, 0, false) // top-left always shown
|
|
@@ -335,8 +349,8 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
335
349
|
) {
|
|
336
350
|
if (!state.showCropHandles) return
|
|
337
351
|
|
|
338
|
-
const {
|
|
339
|
-
const cropStrokeWidth =
|
|
352
|
+
const { handleSize, width, height, hideAlternateCropHandles } = state
|
|
353
|
+
const cropStrokeWidth = handleSize / 3
|
|
340
354
|
const offset = cropStrokeWidth / 2
|
|
341
355
|
|
|
342
356
|
ctx.beginPath()
|
|
@@ -346,41 +360,41 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
346
360
|
ctx.lineJoin = 'miter'
|
|
347
361
|
|
|
348
362
|
// top_left corner (always shown)
|
|
349
|
-
ctx.moveTo(-offset,
|
|
363
|
+
ctx.moveTo(-offset, handleSize)
|
|
350
364
|
ctx.lineTo(-offset, -offset)
|
|
351
|
-
ctx.lineTo(
|
|
365
|
+
ctx.lineTo(handleSize, -offset)
|
|
352
366
|
|
|
353
367
|
// bottom_right corner (always shown)
|
|
354
|
-
ctx.moveTo(width + offset, height -
|
|
368
|
+
ctx.moveTo(width + offset, height - handleSize)
|
|
355
369
|
ctx.lineTo(width + offset, height + offset)
|
|
356
|
-
ctx.lineTo(width -
|
|
370
|
+
ctx.lineTo(width - handleSize, height + offset)
|
|
357
371
|
|
|
358
372
|
if (!hideAlternateCropHandles) {
|
|
359
373
|
// top_right corner
|
|
360
|
-
ctx.moveTo(width -
|
|
374
|
+
ctx.moveTo(width - handleSize, -offset)
|
|
361
375
|
ctx.lineTo(width + offset, -offset)
|
|
362
|
-
ctx.lineTo(width + offset,
|
|
376
|
+
ctx.lineTo(width + offset, handleSize)
|
|
363
377
|
|
|
364
378
|
// bottom_left corner
|
|
365
|
-
ctx.moveTo(
|
|
379
|
+
ctx.moveTo(handleSize, height + offset)
|
|
366
380
|
ctx.lineTo(-offset, height + offset)
|
|
367
|
-
ctx.lineTo(-offset, height -
|
|
381
|
+
ctx.lineTo(-offset, height - handleSize)
|
|
368
382
|
|
|
369
383
|
// top edge
|
|
370
|
-
ctx.moveTo(width / 2 -
|
|
371
|
-
ctx.lineTo(width / 2 +
|
|
384
|
+
ctx.moveTo(width / 2 - handleSize, -offset)
|
|
385
|
+
ctx.lineTo(width / 2 + handleSize, -offset)
|
|
372
386
|
|
|
373
387
|
// right edge
|
|
374
|
-
ctx.moveTo(width + offset, height / 2 -
|
|
375
|
-
ctx.lineTo(width + offset, height / 2 +
|
|
388
|
+
ctx.moveTo(width + offset, height / 2 - handleSize)
|
|
389
|
+
ctx.lineTo(width + offset, height / 2 + handleSize)
|
|
376
390
|
|
|
377
391
|
// bottom edge
|
|
378
|
-
ctx.moveTo(width / 2 -
|
|
379
|
-
ctx.lineTo(width / 2 +
|
|
392
|
+
ctx.moveTo(width / 2 - handleSize, height + offset)
|
|
393
|
+
ctx.lineTo(width / 2 + handleSize, height + offset)
|
|
380
394
|
|
|
381
395
|
// left edge
|
|
382
|
-
ctx.moveTo(-offset, height / 2 -
|
|
383
|
-
ctx.lineTo(-offset, height / 2 +
|
|
396
|
+
ctx.moveTo(-offset, height / 2 - handleSize)
|
|
397
|
+
ctx.lineTo(-offset, height / 2 + handleSize)
|
|
384
398
|
}
|
|
385
399
|
|
|
386
400
|
ctx.stroke()
|
|
@@ -394,7 +408,7 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
394
408
|
if (!state.showMobileRotateHandle) return
|
|
395
409
|
|
|
396
410
|
const { cx, cy } = this._getMobileRotateCenter(state)
|
|
397
|
-
const fgRadius = state.
|
|
411
|
+
const fgRadius = state.handleSize / SQUARE_ROOT_PI
|
|
398
412
|
|
|
399
413
|
ctx.fillStyle = colors.bgColor
|
|
400
414
|
ctx.strokeStyle = colors.strokeColor
|
|
@@ -417,18 +431,18 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
417
431
|
zoom,
|
|
418
432
|
width,
|
|
419
433
|
height,
|
|
420
|
-
|
|
421
|
-
|
|
434
|
+
handleSize,
|
|
435
|
+
hitTargetSizeY,
|
|
422
436
|
} = state
|
|
423
437
|
if (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== 'text') {
|
|
424
438
|
return
|
|
425
439
|
}
|
|
426
440
|
|
|
427
|
-
const textHandleHeight = Math.min(24 / zoom, height -
|
|
441
|
+
const textHandleHeight = Math.min(24 / zoom, height - hitTargetSizeY * 3)
|
|
428
442
|
if (textHandleHeight * zoom < 4) return
|
|
429
443
|
|
|
430
|
-
const hw =
|
|
431
|
-
const r =
|
|
444
|
+
const hw = handleSize / 2
|
|
445
|
+
const r = handleSize / 4
|
|
432
446
|
|
|
433
447
|
ctx.fillStyle = colors.strokeColor
|
|
434
448
|
ctx.beginPath()
|
|
@@ -474,27 +488,31 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
474
488
|
|
|
475
489
|
const width = expandedBounds.width
|
|
476
490
|
const height = expandedBounds.height
|
|
477
|
-
const
|
|
478
|
-
const isTinyX = width <
|
|
479
|
-
const isTinyY = height <
|
|
480
|
-
const isSmallX = width <
|
|
481
|
-
const isSmallY = height <
|
|
482
|
-
const isSmallCropX = width <
|
|
483
|
-
const isSmallCropY = height <
|
|
491
|
+
const handleSize = 8 / zoom
|
|
492
|
+
const isTinyX = width < handleSize * 2
|
|
493
|
+
const isTinyY = height < handleSize * 2
|
|
494
|
+
const isSmallX = width < handleSize * 4
|
|
495
|
+
const isSmallY = height < handleSize * 4
|
|
496
|
+
const isSmallCropX = width < handleSize * 5
|
|
497
|
+
const isSmallCropY = height < handleSize * 5
|
|
484
498
|
|
|
485
499
|
const mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1
|
|
486
|
-
const
|
|
487
|
-
const
|
|
488
|
-
|
|
500
|
+
const hitTargetSize = (6 / zoom) * mobileHandleMultiplier
|
|
501
|
+
const hitTargetSizeX =
|
|
502
|
+
(isSmallX ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)
|
|
503
|
+
const hitTargetSizeY =
|
|
504
|
+
(isSmallY ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)
|
|
489
505
|
|
|
490
|
-
const
|
|
491
|
-
const
|
|
506
|
+
const expandOffsetX = expandedBounds.x - bounds.x
|
|
507
|
+
const expandOffsetY = expandedBounds.y - bounds.y
|
|
492
508
|
|
|
493
509
|
const shouldDisplayControls =
|
|
494
510
|
editor.isInAny(
|
|
495
511
|
'select.idle',
|
|
496
512
|
'select.pointing_selection',
|
|
497
513
|
'select.pointing_shape',
|
|
514
|
+
'select.pointing_resize_handle',
|
|
515
|
+
'select.pointing_rotate_handle',
|
|
498
516
|
'select.crop.idle'
|
|
499
517
|
) &&
|
|
500
518
|
!isChangingStyle &&
|
|
@@ -552,7 +570,8 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
552
570
|
'select.crop.idle',
|
|
553
571
|
'select.crop.pointing_crop',
|
|
554
572
|
'select.crop.pointing_crop_handle',
|
|
555
|
-
'select.pointing_resize_handle'
|
|
573
|
+
'select.pointing_resize_handle',
|
|
574
|
+
'select.pointing_rotate_handle'
|
|
556
575
|
)) ||
|
|
557
576
|
(showSelectionBounds &&
|
|
558
577
|
editor.isIn('select.resizing') &&
|
|
@@ -566,12 +585,12 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
566
585
|
rotation,
|
|
567
586
|
width,
|
|
568
587
|
height,
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
588
|
+
handleSize,
|
|
589
|
+
hitTargetSize,
|
|
590
|
+
hitTargetSizeX,
|
|
591
|
+
hitTargetSizeY,
|
|
592
|
+
expandOffsetX,
|
|
593
|
+
expandOffsetY,
|
|
575
594
|
isSmallX,
|
|
576
595
|
shouldDisplayControls,
|
|
577
596
|
shouldDisplayBox,
|
|
@@ -587,19 +606,19 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
587
606
|
}
|
|
588
607
|
|
|
589
608
|
private _getMobileRotateCenter(state: SelectionState): { cx: number; cy: number } {
|
|
590
|
-
const { width, height,
|
|
609
|
+
const { width, height, hitTargetSize, isSmallX, onlyShape, rotation } = state
|
|
591
610
|
const editor = this.editor
|
|
592
611
|
const isMediaShape =
|
|
593
612
|
!!onlyShape &&
|
|
594
613
|
(editor.isShapeOfType(onlyShape, 'image') || editor.isShapeOfType(onlyShape, 'video'))
|
|
595
614
|
const isShapeTooCloseToContextualToolbar = rotation / HALF_PI > 1.6 && rotation / HALF_PI < 2.4
|
|
596
615
|
|
|
597
|
-
const cx = isSmallX ? -
|
|
616
|
+
const cx = isSmallX ? -hitTargetSize * 1.5 : width / 2
|
|
598
617
|
const cy = isSmallX
|
|
599
618
|
? height / 2
|
|
600
619
|
: isMediaShape && !isShapeTooCloseToContextualToolbar
|
|
601
|
-
? height +
|
|
602
|
-
: -
|
|
620
|
+
? height + hitTargetSize * 1.5
|
|
621
|
+
: -hitTargetSize * 1.5
|
|
603
622
|
return { cx, cy }
|
|
604
623
|
}
|
|
605
624
|
|
|
@@ -627,16 +646,16 @@ export class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForeg
|
|
|
627
646
|
edge: SelectionEdge,
|
|
628
647
|
state: SelectionState
|
|
629
648
|
): { x: number; y: number; w: number; h: number } {
|
|
630
|
-
const { width, height,
|
|
649
|
+
const { width, height, hitTargetSizeX, hitTargetSizeY } = state
|
|
631
650
|
switch (edge) {
|
|
632
651
|
case 'top':
|
|
633
|
-
return { x: 0, y: -
|
|
652
|
+
return { x: 0, y: -hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }
|
|
634
653
|
case 'right':
|
|
635
|
-
return { x: width -
|
|
654
|
+
return { x: width - hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }
|
|
636
655
|
case 'bottom':
|
|
637
|
-
return { x: 0, y: height -
|
|
656
|
+
return { x: 0, y: height - hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }
|
|
638
657
|
case 'left':
|
|
639
|
-
return { x: -
|
|
658
|
+
return { x: -hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }
|
|
640
659
|
}
|
|
641
660
|
}
|
|
642
661
|
|
|
@@ -38,7 +38,9 @@ export class ShapeHandleOverlayUtil extends OverlayUtil<TLShapeHandleOverlay> {
|
|
|
38
38
|
const handles = editor.getShapeHandles(onlySelectedShape)
|
|
39
39
|
if (!handles) return false
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
// Not shown in select.pointing_shape: hiding handles on pointer down
|
|
42
|
+
// matches the arrow binding hint, which also waits for pointer up.
|
|
43
|
+
if (editor.isInAny('select.idle', 'select.pointing_handle')) {
|
|
42
44
|
return true
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { OverlayUtil, strokeShapeIndicators, TLOverlay } from '@tldraw/editor'
|
|
2
|
+
import { computed } from '@tldraw/state'
|
|
3
|
+
import { TLShapeId } from '@tldraw/tlschema'
|
|
4
|
+
|
|
5
|
+
/** @public */
|
|
6
|
+
export interface TLShapeIndicatorOverlay extends TLOverlay {
|
|
7
|
+
props: {
|
|
8
|
+
idsToDisplay: TLShapeId[]
|
|
9
|
+
hintingShapeIds: TLShapeId[]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface RelevantInstanceFlags {
|
|
14
|
+
isChangingStyle: boolean
|
|
15
|
+
isHoveringCanvas: boolean | null
|
|
16
|
+
isCoarsePointer: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Overlay util for shape indicators — the selection / hover / hint outlines drawn
|
|
21
|
+
* under the selection foreground. Paints local indicators in the theme's
|
|
22
|
+
* selection color.
|
|
23
|
+
*
|
|
24
|
+
* Remote collaborator selection indicators are drawn by a separate overlay util
|
|
25
|
+
* (e.g. `CollaboratorShapeIndicatorOverlayUtil` from `tldraw`) that runs at a
|
|
26
|
+
* lower z-index so peer selections appear under the local indicators.
|
|
27
|
+
*
|
|
28
|
+
* Non-interactive: contributes no hit-test geometry.
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export class ShapeIndicatorOverlayUtil extends OverlayUtil<TLShapeIndicatorOverlay> {
|
|
33
|
+
static override type = 'shape_indicator'
|
|
34
|
+
override options = { zIndex: 50, lineWidth: 1.5, hintedLineWidth: 2.5 }
|
|
35
|
+
|
|
36
|
+
// Narrow projection of instance state. Reading the full record would
|
|
37
|
+
// re-fire getOverlays on every cursor move / brush update; gating on these
|
|
38
|
+
// three booleans means we only re-fire when one of them actually flips.
|
|
39
|
+
private _instanceFlags$ = computed<RelevantInstanceFlags>(
|
|
40
|
+
'shape indicator instance flags',
|
|
41
|
+
() => {
|
|
42
|
+
const i = this.editor.getInstanceState()
|
|
43
|
+
return {
|
|
44
|
+
isChangingStyle: i.isChangingStyle,
|
|
45
|
+
isHoveringCanvas: i.isHoveringCanvas,
|
|
46
|
+
isCoarsePointer: i.isCoarsePointer,
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
isEqual: (a, b) =>
|
|
51
|
+
a.isChangingStyle === b.isChangingStyle &&
|
|
52
|
+
a.isHoveringCanvas === b.isHoveringCanvas &&
|
|
53
|
+
a.isCoarsePointer === b.isCoarsePointer,
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
override isActive(): boolean {
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override getOverlays(): TLShapeIndicatorOverlay[] {
|
|
62
|
+
const editor = this.editor
|
|
63
|
+
const renderingShapeIds = new Set(editor.getRenderingShapes().map((s) => s.id))
|
|
64
|
+
|
|
65
|
+
// Local selected / hovered indicators.
|
|
66
|
+
const idsToDisplay: TLShapeId[] = []
|
|
67
|
+
const { isChangingStyle, isHoveringCanvas, isCoarsePointer } = this._instanceFlags$.get()
|
|
68
|
+
const isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')
|
|
69
|
+
const isInSelectState = editor.isInAny(
|
|
70
|
+
'select.brushing',
|
|
71
|
+
'select.scribble_brushing',
|
|
72
|
+
'select.pointing_shape',
|
|
73
|
+
'select.pointing_selection',
|
|
74
|
+
'select.pointing_handle',
|
|
75
|
+
'select.pointing_resize_handle',
|
|
76
|
+
'select.pointing_rotate_handle'
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
if (!isChangingStyle && (isIdleOrEditing || isInSelectState)) {
|
|
80
|
+
for (const id of editor.getSelectedShapeIds()) {
|
|
81
|
+
if (renderingShapeIds.has(id)) idsToDisplay.push(id)
|
|
82
|
+
}
|
|
83
|
+
if (isIdleOrEditing && isHoveringCanvas && !isCoarsePointer) {
|
|
84
|
+
const hovered = editor.getHoveredShapeId()
|
|
85
|
+
if (hovered && renderingShapeIds.has(hovered) && !idsToDisplay.includes(hovered)) {
|
|
86
|
+
idsToDisplay.push(hovered)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Hinted shapes (drawn thicker). Already deduped at write time in
|
|
92
|
+
// `updateHintingShapeIds`, so no need to dedupe again here.
|
|
93
|
+
const hintingShapeIds: TLShapeId[] = []
|
|
94
|
+
for (const id of editor.getHintingShapeIds()) {
|
|
95
|
+
if (renderingShapeIds.has(id)) hintingShapeIds.push(id)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (idsToDisplay.length === 0 && hintingShapeIds.length === 0) {
|
|
99
|
+
return []
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return [
|
|
103
|
+
{
|
|
104
|
+
id: 'shape_indicator',
|
|
105
|
+
type: 'shape_indicator',
|
|
106
|
+
props: { idsToDisplay, hintingShapeIds },
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
override render(ctx: CanvasRenderingContext2D, overlays: TLShapeIndicatorOverlay[]): void {
|
|
112
|
+
const overlay = overlays[0]
|
|
113
|
+
if (!overlay) return
|
|
114
|
+
|
|
115
|
+
const editor = this.editor
|
|
116
|
+
const zoom = editor.getZoomLevel()
|
|
117
|
+
const { idsToDisplay, hintingShapeIds } = overlay.props
|
|
118
|
+
|
|
119
|
+
ctx.lineCap = 'round'
|
|
120
|
+
ctx.lineJoin = 'round'
|
|
121
|
+
|
|
122
|
+
// Local selected / hovered indicators — one stroke call for the whole batch.
|
|
123
|
+
ctx.strokeStyle = editor.getCurrentTheme().colors[editor.getColorMode()].selectionStroke
|
|
124
|
+
ctx.lineWidth = this.options.lineWidth / zoom
|
|
125
|
+
strokeShapeIndicators(editor, ctx, idsToDisplay)
|
|
126
|
+
|
|
127
|
+
// Hinted shapes — thicker stroke, one call for the whole batch.
|
|
128
|
+
if (hintingShapeIds.length > 0) {
|
|
129
|
+
ctx.lineWidth = this.options.hintedLineWidth / zoom
|
|
130
|
+
strokeShapeIndicators(editor, ctx, hintingShapeIds)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
StateNode,
|
|
3
|
+
TLArrowShape,
|
|
4
|
+
createShapeId,
|
|
5
|
+
cancelShapeCreationOnLongPress,
|
|
6
|
+
maybeSnapToGrid,
|
|
7
|
+
} from '@tldraw/editor'
|
|
2
8
|
import { ArrowShapeUtil } from '../ArrowShapeUtil'
|
|
3
9
|
import { clearArrowTargetState, updateArrowTargetState } from '../arrowTargetState'
|
|
4
10
|
|
|
@@ -69,6 +75,10 @@ export class Pointing extends StateNode {
|
|
|
69
75
|
this.cancel()
|
|
70
76
|
}
|
|
71
77
|
|
|
78
|
+
override onLongPress() {
|
|
79
|
+
cancelShapeCreationOnLongPress(this.editor, () => this.cancel())
|
|
80
|
+
}
|
|
81
|
+
|
|
72
82
|
override onCancel() {
|
|
73
83
|
this.cancel()
|
|
74
84
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BaseBoxShapeUtil,
|
|
4
4
|
HTMLContainer,
|
|
5
|
+
Rectangle2d,
|
|
5
6
|
T,
|
|
6
7
|
TLAssetId,
|
|
7
8
|
TLBookmarkAsset,
|
|
@@ -24,7 +25,9 @@ import { getRotatedBoxShadow } from '../shared/rotated-box-shadow'
|
|
|
24
25
|
import {
|
|
25
26
|
BOOKMARK_HEIGHT,
|
|
26
27
|
BOOKMARK_WIDTH,
|
|
28
|
+
getBookmarkShapeHeight,
|
|
27
29
|
getHumanReadableAddress,
|
|
30
|
+
getResolvedBookmarkAssetId,
|
|
28
31
|
setBookmarkHeight,
|
|
29
32
|
updateBookmarkAssetOnUrlChange,
|
|
30
33
|
} from './bookmarks'
|
|
@@ -87,8 +90,17 @@ export class BookmarkShapeUtil extends BaseBoxShapeUtil<TLBookmarkShape> {
|
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
override getGeometry(shape: TLBookmarkShape) {
|
|
94
|
+
return new Rectangle2d({
|
|
95
|
+
width: shape.props.w,
|
|
96
|
+
height: getBookmarkShapeHeight(this.editor, shape),
|
|
97
|
+
isFilled: true,
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
override component(shape: TLBookmarkShape) {
|
|
91
|
-
const { assetId, url
|
|
102
|
+
const { assetId, url } = shape.props
|
|
103
|
+
const h = getBookmarkShapeHeight(this.editor, shape)
|
|
92
104
|
const rotation = this.editor.getShapePageTransform(shape)!.rotation()
|
|
93
105
|
|
|
94
106
|
return <BookmarkShapeComponent assetId={assetId} url={url} h={h} rotation={rotation} />
|
|
@@ -96,7 +108,7 @@ export class BookmarkShapeUtil extends BaseBoxShapeUtil<TLBookmarkShape> {
|
|
|
96
108
|
|
|
97
109
|
override getIndicatorPath(shape: TLBookmarkShape): Path2D {
|
|
98
110
|
const path = new Path2D()
|
|
99
|
-
path.rect(0, 0, shape.props.w, shape
|
|
111
|
+
path.rect(0, 0, shape.props.w, getBookmarkShapeHeight(this.editor, shape))
|
|
100
112
|
return path
|
|
101
113
|
}
|
|
102
114
|
|
|
@@ -147,7 +159,8 @@ export function BookmarkShapeComponent({
|
|
|
147
159
|
}) {
|
|
148
160
|
const editor = useEditor()
|
|
149
161
|
|
|
150
|
-
const
|
|
162
|
+
const resolvedAssetId = getResolvedBookmarkAssetId(editor, assetId, url)
|
|
163
|
+
const asset = resolvedAssetId ? (editor.getAsset(resolvedAssetId) as TLBookmarkAsset) : null
|
|
151
164
|
|
|
152
165
|
const isSafariExport = !!useSvgExportContext() && tlenv.isSafari
|
|
153
166
|
|