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
package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx
CHANGED
|
@@ -12,8 +12,10 @@ export function DefaultKeyboardShortcutsDialogContent() {
|
|
|
12
12
|
<TldrawUiMenuGroup label="shortcuts-dialog.tools" id="tools">
|
|
13
13
|
<TldrawUiMenuActionItem actionId="toggle-tool-lock" />
|
|
14
14
|
<TldrawUiMenuActionItem actionId="insert-media" />
|
|
15
|
+
<TldrawUiMenuActionItem actionId="insert-embed" />
|
|
15
16
|
<TldrawUiMenuToolItem toolId="select" />
|
|
16
17
|
<TldrawUiMenuToolItem toolId="draw" />
|
|
18
|
+
<TldrawUiMenuToolItem toolId="highlight" />
|
|
17
19
|
<TldrawUiMenuToolItem toolId="eraser" />
|
|
18
20
|
<TldrawUiMenuToolItem toolId="hand" />
|
|
19
21
|
<TldrawUiMenuToolItem toolId="rectangle" />
|
|
@@ -43,10 +45,13 @@ export function DefaultKeyboardShortcutsDialogContent() {
|
|
|
43
45
|
<TldrawUiMenuActionItem actionId="redo" />
|
|
44
46
|
<TldrawUiMenuActionItem actionId="cut" />
|
|
45
47
|
<TldrawUiMenuActionItem actionId="copy" />
|
|
48
|
+
<TldrawUiMenuActionItem actionId="copy-as-png" />
|
|
49
|
+
<TldrawUiMenuActionItem actionId="copy-hovered-styles" />
|
|
46
50
|
<TldrawUiMenuActionItem actionId="paste" />
|
|
47
51
|
<TldrawUiMenuActionItem actionId="select-all" />
|
|
48
52
|
<TldrawUiMenuActionItem actionId="delete" />
|
|
49
53
|
<TldrawUiMenuActionItem actionId="duplicate" />
|
|
54
|
+
<TldrawUiMenuActionItem actionId="print" />
|
|
50
55
|
</TldrawUiMenuGroup>
|
|
51
56
|
<TldrawUiMenuGroup label="shortcuts-dialog.view" id="view">
|
|
52
57
|
<TldrawUiMenuActionItem actionId="select-zoom-tool" />
|
|
@@ -71,6 +76,9 @@ export function DefaultKeyboardShortcutsDialogContent() {
|
|
|
71
76
|
<TldrawUiMenuActionItem actionId="send-to-back" />
|
|
72
77
|
<TldrawUiMenuActionItem actionId="group" />
|
|
73
78
|
<TldrawUiMenuActionItem actionId="ungroup" />
|
|
79
|
+
<TldrawUiMenuActionItem actionId="frame-selection" />
|
|
80
|
+
<TldrawUiMenuActionItem actionId="flatten-to-image" />
|
|
81
|
+
<TldrawUiMenuActionItem actionId="toggle-lock" />
|
|
74
82
|
<TldrawUiMenuActionItem actionId="flip-horizontal" />
|
|
75
83
|
<TldrawUiMenuActionItem actionId="flip-vertical" />
|
|
76
84
|
<TldrawUiMenuActionItem actionId="align-top" />
|
|
@@ -79,6 +87,8 @@ export function DefaultKeyboardShortcutsDialogContent() {
|
|
|
79
87
|
<TldrawUiMenuActionItem actionId="align-left" />
|
|
80
88
|
<TldrawUiMenuActionItem actionId="align-center-horizontal" />
|
|
81
89
|
<TldrawUiMenuActionItem actionId="align-right" />
|
|
90
|
+
<TldrawUiMenuActionItem actionId="distribute-horizontal" />
|
|
91
|
+
<TldrawUiMenuActionItem actionId="distribute-vertical" />
|
|
82
92
|
</TldrawUiMenuGroup>
|
|
83
93
|
<TldrawUiMenuGroup label="shortcuts-dialog.text-formatting" id="text">
|
|
84
94
|
<TldrawUiMenuItem
|
|
@@ -15,6 +15,11 @@ import * as React from 'react'
|
|
|
15
15
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
16
16
|
import { MinimapManager } from './MinimapManager'
|
|
17
17
|
|
|
18
|
+
// Squared distance (in screen pixels) the pointer can move after pointer down before
|
|
19
|
+
// it counts as a drag. Sub-pixel jitter that accompanies a click stays below this, so
|
|
20
|
+
// it doesn't recenter the camera instantly and cut off the easing animation.
|
|
21
|
+
const CLICK_JITTER_THRESHOLD_SQ = 4
|
|
22
|
+
|
|
18
23
|
/** @public @react */
|
|
19
24
|
export function DefaultMinimap() {
|
|
20
25
|
const editor = useEditor()
|
|
@@ -24,6 +29,7 @@ export function DefaultMinimap() {
|
|
|
24
29
|
const rCanvas = React.useRef<HTMLCanvasElement>(null!)
|
|
25
30
|
const rPointing = React.useRef(false)
|
|
26
31
|
const rActivePointerId = React.useRef<number | null>(null)
|
|
32
|
+
const rOriginScreenPoint = React.useRef(new Vec())
|
|
27
33
|
|
|
28
34
|
const minimapRef = React.useRef<MinimapManager | undefined>(undefined)
|
|
29
35
|
|
|
@@ -47,25 +53,18 @@ export function DefaultMinimap() {
|
|
|
47
53
|
const onDoubleClick = React.useCallback(
|
|
48
54
|
(e: React.MouseEvent<HTMLCanvasElement>) => {
|
|
49
55
|
if (!editor.getCurrentPageShapeIds().size) return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const point = minimapRef.current.minimapScreenPointToPagePoint(
|
|
53
|
-
e.clientX,
|
|
54
|
-
e.clientY,
|
|
55
|
-
false,
|
|
56
|
-
false
|
|
57
|
-
)
|
|
56
|
+
const minimap = minimapRef.current
|
|
57
|
+
if (!minimap) return
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
e.clientX,
|
|
61
|
-
e.clientY,
|
|
62
|
-
false,
|
|
63
|
-
true
|
|
64
|
-
)
|
|
59
|
+
const { clientX: x, clientY: y } = e
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
// Stash the clamped point / clamped viewport page center
|
|
62
|
+
const clampedPoint = minimap.minimapScreenPointToPagePoint(x, y, false, true)
|
|
63
|
+
minimap.originPagePoint.setTo(clampedPoint)
|
|
64
|
+
minimap.originPageCenter.setTo(editor.getViewportPageBounds().center)
|
|
68
65
|
|
|
66
|
+
// Then center on the unclamped point
|
|
67
|
+
const point = minimap.minimapScreenPointToPagePoint(x, y, false, false)
|
|
69
68
|
editor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })
|
|
70
69
|
},
|
|
71
70
|
[editor]
|
|
@@ -73,54 +72,49 @@ export function DefaultMinimap() {
|
|
|
73
72
|
|
|
74
73
|
const onPointerDown = React.useCallback(
|
|
75
74
|
(e: React.PointerEvent<HTMLCanvasElement>) => {
|
|
76
|
-
|
|
75
|
+
const minimap = minimapRef.current
|
|
76
|
+
if (!minimap) return
|
|
77
77
|
if (e.button !== 0) return
|
|
78
78
|
|
|
79
79
|
const elm = e.currentTarget
|
|
80
80
|
setPointerCapture(elm, e)
|
|
81
81
|
if (!editor.getCurrentPageShapeIds().size) return
|
|
82
82
|
|
|
83
|
+
const { clientX: x, clientY: y } = e
|
|
84
|
+
|
|
83
85
|
rPointing.current = true
|
|
84
86
|
rActivePointerId.current = e.pointerId
|
|
87
|
+
rOriginScreenPoint.current = new Vec(x, y)
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
minimap.isInViewport = false
|
|
87
90
|
|
|
88
|
-
const point =
|
|
89
|
-
e.clientX,
|
|
90
|
-
e.clientY,
|
|
91
|
-
false,
|
|
92
|
-
false
|
|
93
|
-
)
|
|
91
|
+
const point = minimap.minimapScreenPointToPagePoint(x, y, false, false)
|
|
94
92
|
|
|
95
|
-
const
|
|
96
|
-
const commonBounds =
|
|
93
|
+
const vpPageBounds = editor.getViewportPageBounds()
|
|
94
|
+
const commonBounds = minimap.getContentPageBounds()
|
|
97
95
|
const allowedBounds = new Box(
|
|
98
|
-
commonBounds.x -
|
|
99
|
-
commonBounds.y -
|
|
100
|
-
commonBounds.width +
|
|
101
|
-
commonBounds.height +
|
|
96
|
+
commonBounds.x - vpPageBounds.width / 2,
|
|
97
|
+
commonBounds.y - vpPageBounds.height / 2,
|
|
98
|
+
commonBounds.width + vpPageBounds.width,
|
|
99
|
+
commonBounds.height + vpPageBounds.height
|
|
102
100
|
)
|
|
103
101
|
|
|
104
102
|
// If we clicked inside of the allowed area, but outside of the viewport
|
|
105
|
-
if (allowedBounds.containsPoint(point) && !
|
|
106
|
-
|
|
107
|
-
const delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)
|
|
103
|
+
if (allowedBounds.containsPoint(point) && !vpPageBounds.containsPoint(point)) {
|
|
104
|
+
const delta = Vec.Sub(vpPageBounds.center, vpPageBounds.point)
|
|
108
105
|
const pagePoint = Vec.Add(point, delta)
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
minimap.originPagePoint.setTo(pagePoint)
|
|
107
|
+
minimap.originPageCenter.setTo(point)
|
|
111
108
|
editor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })
|
|
112
109
|
} else {
|
|
113
|
-
const clampedPoint =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
true
|
|
118
|
-
)
|
|
119
|
-
minimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)
|
|
120
|
-
minimapRef.current.originPagePoint.setTo(clampedPoint)
|
|
121
|
-
minimapRef.current.originPageCenter.setTo(_vpPageBounds.center)
|
|
110
|
+
const clampedPoint = minimap.minimapScreenPointToPagePoint(x, y, false, true)
|
|
111
|
+
minimap.isInViewport = vpPageBounds.containsPoint(clampedPoint)
|
|
112
|
+
minimap.originPagePoint.setTo(clampedPoint)
|
|
113
|
+
minimap.originPageCenter.setTo(vpPageBounds.center)
|
|
122
114
|
}
|
|
123
115
|
|
|
116
|
+
const body = editor.getContainerDocument().body
|
|
117
|
+
|
|
124
118
|
function endDrag() {
|
|
125
119
|
if (rActivePointerId.current !== null && elm.hasPointerCapture(rActivePointerId.current)) {
|
|
126
120
|
elm.releasePointerCapture(rActivePointerId.current)
|
|
@@ -128,44 +122,36 @@ export function DefaultMinimap() {
|
|
|
128
122
|
|
|
129
123
|
rPointing.current = false
|
|
130
124
|
rActivePointerId.current = null
|
|
131
|
-
body.removeEventListener('pointerup',
|
|
132
|
-
body.removeEventListener('pointercancel',
|
|
133
|
-
body.removeEventListener('contextmenu',
|
|
125
|
+
body.removeEventListener('pointerup', endDrag)
|
|
126
|
+
body.removeEventListener('pointercancel', endDrag)
|
|
127
|
+
body.removeEventListener('contextmenu', endDrag, true)
|
|
134
128
|
}
|
|
135
129
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
function onPointerCancel() {
|
|
140
|
-
endDrag()
|
|
141
|
-
}
|
|
142
|
-
function onContextMenu() {
|
|
143
|
-
endDrag()
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const body = editor.getContainerDocument().body
|
|
147
|
-
body.addEventListener('pointerup', onPointerUp)
|
|
148
|
-
body.addEventListener('pointercancel', onPointerCancel)
|
|
149
|
-
body.addEventListener('contextmenu', onContextMenu, true)
|
|
130
|
+
body.addEventListener('pointerup', endDrag)
|
|
131
|
+
body.addEventListener('pointercancel', endDrag)
|
|
132
|
+
body.addEventListener('contextmenu', endDrag, true)
|
|
150
133
|
},
|
|
151
134
|
[editor]
|
|
152
135
|
)
|
|
153
136
|
|
|
154
137
|
const onPointerMove = React.useCallback(
|
|
155
138
|
(e: React.PointerEvent<HTMLCanvasElement>) => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
)
|
|
139
|
+
const minimap = minimapRef.current
|
|
140
|
+
if (!minimap) return
|
|
141
|
+
|
|
142
|
+
const { clientX: x, clientY: y } = e
|
|
143
|
+
|
|
144
|
+
const point = minimap.minimapScreenPointToPagePoint(x, y, e.shiftKey, true)
|
|
163
145
|
|
|
164
146
|
if (rPointing.current) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
147
|
+
// Ignore the sub-pixel pointer jitter that accompanies a click, so it doesn't
|
|
148
|
+
// cut off the easing animation started on pointer down.
|
|
149
|
+
if (Vec.Dist2(rOriginScreenPoint.current, new Vec(x, y)) <= CLICK_JITTER_THRESHOLD_SQ) {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (minimap.isInViewport) {
|
|
154
|
+
const delta = minimap.originPagePoint.clone().sub(minimap.originPageCenter)
|
|
169
155
|
editor.centerOnPoint(Vec.Sub(point, delta))
|
|
170
156
|
return
|
|
171
157
|
}
|
|
@@ -173,7 +159,7 @@ export function DefaultMinimap() {
|
|
|
173
159
|
editor.centerOnPoint(point)
|
|
174
160
|
}
|
|
175
161
|
|
|
176
|
-
const pagePoint =
|
|
162
|
+
const pagePoint = minimap.getMinimapPagePoint(x, y)
|
|
177
163
|
|
|
178
164
|
const screenPoint = editor.pageToScreen(pagePoint)
|
|
179
165
|
|
|
@@ -225,10 +211,10 @@ export function DefaultMinimap() {
|
|
|
225
211
|
return (
|
|
226
212
|
<div className="tlui-minimap">
|
|
227
213
|
<canvas
|
|
214
|
+
ref={rCanvas}
|
|
228
215
|
role="img"
|
|
229
216
|
aria-label={msg('navigation-zone.minimap')}
|
|
230
217
|
data-testid="minimap.canvas"
|
|
231
|
-
ref={rCanvas}
|
|
232
218
|
className="tlui-minimap__canvas"
|
|
233
219
|
onDoubleClick={onDoubleClick}
|
|
234
220
|
onPointerMove={onPointerMove}
|
|
@@ -17,7 +17,7 @@ export class MinimapManager {
|
|
|
17
17
|
|
|
18
18
|
@bind
|
|
19
19
|
close() {
|
|
20
|
-
|
|
20
|
+
this.disposables.forEach((d) => d())
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
private readonly ctx: CanvasRenderingContext2D
|
|
@@ -78,16 +78,6 @@ export class MinimapManager {
|
|
|
78
78
|
: viewportPageBounds
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
@computed
|
|
82
|
-
getContentScreenBounds() {
|
|
83
|
-
const contentPageBounds = this.getContentPageBounds()
|
|
84
|
-
const topLeft = this.editor.pageToScreen(contentPageBounds.point)
|
|
85
|
-
const bottomRight = this.editor.pageToScreen(
|
|
86
|
-
new Vec(contentPageBounds.maxX, contentPageBounds.maxY)
|
|
87
|
-
)
|
|
88
|
-
return new Box(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
81
|
private _getCanvasBoundingRect() {
|
|
92
82
|
const { x, y, width, height } = this.elem.getBoundingClientRect()
|
|
93
83
|
return new Box(x, y, width, height)
|
|
@@ -116,11 +106,6 @@ export class MinimapManager {
|
|
|
116
106
|
return new Vec(rect.width * dpr, rect.height * dpr)
|
|
117
107
|
}
|
|
118
108
|
|
|
119
|
-
@computed
|
|
120
|
-
getCanvasClientPosition() {
|
|
121
|
-
return this.canvasBoundingClientRect.get().point
|
|
122
|
-
}
|
|
123
|
-
|
|
124
109
|
originPagePoint = new Vec()
|
|
125
110
|
originPageCenter = new Vec()
|
|
126
111
|
|
|
@@ -209,6 +194,29 @@ export class MinimapManager {
|
|
|
209
194
|
return new Vec(px, py)
|
|
210
195
|
}
|
|
211
196
|
|
|
197
|
+
// Shape geometry in page space, split into unselected/selected fills. Built
|
|
198
|
+
// from the per-shape rect cache and selection only, so it survives pan/zoom of
|
|
199
|
+
// the main canvas — those move the `ctx` transform, not the paths themselves.
|
|
200
|
+
@computed
|
|
201
|
+
private getShapePaths() {
|
|
202
|
+
const { editor } = this
|
|
203
|
+
const selectedIds = new Set<string>(editor.getSelectedShapeIds())
|
|
204
|
+
const ids = editor.getCurrentPageShapeIdsSorted()
|
|
205
|
+
|
|
206
|
+
const shapes = new Path2D()
|
|
207
|
+
const selected = new Path2D()
|
|
208
|
+
|
|
209
|
+
for (let i = 0, len = ids.length; i < len; i++) {
|
|
210
|
+
const shapeId = ids[i]
|
|
211
|
+
const bounds = this.shapeRectCache.get(shapeId)
|
|
212
|
+
if (!bounds) continue
|
|
213
|
+
const target = selectedIds.has(shapeId) ? selected : shapes
|
|
214
|
+
target.rect(bounds.x, bounds.y, bounds.w, bounds.h)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return { shapes, selected }
|
|
218
|
+
}
|
|
219
|
+
|
|
212
220
|
@bind
|
|
213
221
|
render() {
|
|
214
222
|
const { ctx, editor, elem } = this
|
|
@@ -234,21 +242,9 @@ export class MinimapManager {
|
|
|
234
242
|
ctx.scale(dpr * zoom, dpr * zoom)
|
|
235
243
|
ctx.translate(-canvasPageBounds.minX, -canvasPageBounds.minY)
|
|
236
244
|
|
|
237
|
-
// Shapes —
|
|
238
|
-
//
|
|
239
|
-
const
|
|
240
|
-
const ids = editor.getCurrentPageShapeIdsSorted()
|
|
241
|
-
|
|
242
|
-
const shapesPath = new Path2D()
|
|
243
|
-
const selectedPath = new Path2D()
|
|
244
|
-
|
|
245
|
-
for (let i = 0, len = ids.length; i < len; i++) {
|
|
246
|
-
const shapeId = ids[i]
|
|
247
|
-
const bounds = this.shapeRectCache.get(shapeId)
|
|
248
|
-
if (!bounds) continue
|
|
249
|
-
const target = selectedIds.has(shapeId) ? selectedPath : shapesPath
|
|
250
|
-
target.rect(bounds.x, bounds.y, bounds.w, bounds.h)
|
|
251
|
-
}
|
|
245
|
+
// Shapes — page-space paths from a computed, so a pan/zoom that only moves
|
|
246
|
+
// the transform above reuses them instead of rebuilding per shape.
|
|
247
|
+
const { shapes: shapesPath, selected: selectedPath } = this.getShapePaths()
|
|
252
248
|
|
|
253
249
|
ctx.fillStyle = this.colors.shapeFill
|
|
254
250
|
ctx.fill(shapesPath)
|
|
@@ -256,13 +252,18 @@ export class MinimapManager {
|
|
|
256
252
|
ctx.fillStyle = this.colors.selectFill
|
|
257
253
|
ctx.fill(selectedPath)
|
|
258
254
|
|
|
259
|
-
// Viewport
|
|
255
|
+
// Viewport indicator. roundRect is pricier than rect, so when the corner
|
|
256
|
+
// radius would be sub-pixel on screen (and thus invisible) fall back to a
|
|
257
|
+
// plain rect.
|
|
260
258
|
const viewport = editor.getViewportPageBounds()
|
|
261
259
|
const { minX: vx, minY: vy, width: vw, height: vh } = viewport
|
|
262
260
|
const r = Math.min(vw / 4, vh / 4, 4 / zoom)
|
|
263
261
|
ctx.beginPath()
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
if (r * zoom < 1) {
|
|
263
|
+
ctx.rect(vx, vy, vw, vh)
|
|
264
|
+
} else {
|
|
265
|
+
ctx.roundRect(vx, vy, vw, vh, r)
|
|
266
|
+
}
|
|
266
267
|
ctx.fillStyle = this.colors.viewportFill
|
|
267
268
|
ctx.fill()
|
|
268
269
|
|
|
@@ -276,26 +277,3 @@ export class MinimapManager {
|
|
|
276
277
|
}
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
|
-
|
|
280
|
-
function roundedRect(
|
|
281
|
-
ctx: CanvasRenderingContext2D | Path2D,
|
|
282
|
-
x: number,
|
|
283
|
-
y: number,
|
|
284
|
-
w: number,
|
|
285
|
-
h: number,
|
|
286
|
-
r: number
|
|
287
|
-
) {
|
|
288
|
-
if (r < 1) {
|
|
289
|
-
ctx.rect(x, y, w, h)
|
|
290
|
-
return
|
|
291
|
-
}
|
|
292
|
-
ctx.moveTo(x + r, y)
|
|
293
|
-
ctx.lineTo(x + w - r, y)
|
|
294
|
-
ctx.quadraticCurveTo(x + w, y, x + w, y + r)
|
|
295
|
-
ctx.lineTo(x + w, y + h - r)
|
|
296
|
-
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h)
|
|
297
|
-
ctx.lineTo(x + r, y + h)
|
|
298
|
-
ctx.quadraticCurveTo(x, y + h, x, y + h - r)
|
|
299
|
-
ctx.lineTo(x, y + r)
|
|
300
|
-
ctx.quadraticCurveTo(x, y, x + r, y)
|
|
301
|
-
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { TLUserId } from '@tldraw/editor'
|
|
1
2
|
import { PORTRAIT_BREAKPOINT } from '../../constants'
|
|
2
3
|
import { useBreakpoint } from '../../context/breakpoints'
|
|
3
4
|
import { useTldrawUiComponents } from '../../context/components'
|
|
4
5
|
|
|
5
6
|
/** @public */
|
|
6
7
|
export interface TLUiPeopleMenuFacePileProps {
|
|
7
|
-
userIds:
|
|
8
|
+
userIds: TLUserId[]
|
|
8
9
|
userName: string
|
|
9
10
|
userColor: string
|
|
10
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { track, useEditor, usePresence } from '@tldraw/editor'
|
|
1
|
+
import { TLUserId, track, useEditor, usePresence } from '@tldraw/editor'
|
|
2
2
|
import { useCallback } from 'react'
|
|
3
3
|
import { useUiEvents } from '../../context/events'
|
|
4
4
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
@@ -9,7 +9,7 @@ import { TldrawUiIcon } from '../primitives/TldrawUiIcon'
|
|
|
9
9
|
|
|
10
10
|
/** @public */
|
|
11
11
|
export interface TLUiPeopleMenuItemProps {
|
|
12
|
-
userId:
|
|
12
|
+
userId: TLUserId
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/** @public @react */
|
|
@@ -32,7 +32,7 @@ export const DefaultPeopleMenuItem = track(function DefaultPeopleMenuItem({
|
|
|
32
32
|
}
|
|
33
33
|
}, [editor, userId, trackEvent])
|
|
34
34
|
|
|
35
|
-
const theyAreFollowingYou = presence?.followingUserId === editor.user.
|
|
35
|
+
const theyAreFollowingYou = presence?.followingUserId === editor.user.getRecordId()
|
|
36
36
|
const youAreFollowingThem = editor.getInstanceState().followingUserId === userId
|
|
37
37
|
|
|
38
38
|
if (!presence) return null
|
|
@@ -123,6 +123,11 @@ function StylePanelButtonPickerInlineInner<T extends string>(
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const handleButtonPointerUp = (e: React.PointerEvent<HTMLButtonElement>) => {
|
|
126
|
+
// Only apply on release if the scrub started in this picker. Otherwise
|
|
127
|
+
// releasing over a different style section selects that section's
|
|
128
|
+
// option, even though scrubbing can't cross sections. See #9223.
|
|
129
|
+
if (!rPointing.current) return
|
|
130
|
+
|
|
126
131
|
const { id } = e.currentTarget.dataset
|
|
127
132
|
if (value.type === 'shared' && value.value === id) return
|
|
128
133
|
|
|
@@ -103,6 +103,14 @@ export function UngroupMenuItem() {
|
|
|
103
103
|
return <TldrawUiMenuActionItem actionId="ungroup" />
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/** @public @react */
|
|
107
|
+
export function FrameSelectionMenuItem() {
|
|
108
|
+
const shouldDisplay = useAllowGroup()
|
|
109
|
+
if (!shouldDisplay) return null
|
|
110
|
+
|
|
111
|
+
return <TldrawUiMenuActionItem actionId="frame-selection" />
|
|
112
|
+
}
|
|
113
|
+
|
|
106
114
|
/** @public @react */
|
|
107
115
|
export function RemoveFrameMenuItem() {
|
|
108
116
|
const editor = useEditor()
|
|
@@ -343,6 +351,7 @@ export function EditMenuSubmenu() {
|
|
|
343
351
|
<GroupMenuItem />
|
|
344
352
|
<UngroupMenuItem />
|
|
345
353
|
<FlattenMenuItem />
|
|
354
|
+
<FrameSelectionMenuItem />
|
|
346
355
|
<EditLinkMenuItem />
|
|
347
356
|
<FitFrameToContentMenuItem />
|
|
348
357
|
<RemoveFrameMenuItem />
|
|
@@ -68,6 +68,7 @@ export interface TLUiDropdownMenuContentProps {
|
|
|
68
68
|
align?: 'start' | 'center' | 'end'
|
|
69
69
|
sideOffset?: number
|
|
70
70
|
alignOffset?: number
|
|
71
|
+
collisionPadding?: number
|
|
71
72
|
children: ReactNode
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -78,6 +79,7 @@ export function TldrawUiDropdownMenuContent({
|
|
|
78
79
|
align = 'start',
|
|
79
80
|
sideOffset = 8,
|
|
80
81
|
alignOffset = 8,
|
|
82
|
+
collisionPadding = 4,
|
|
81
83
|
children,
|
|
82
84
|
}: TLUiDropdownMenuContentProps) {
|
|
83
85
|
const container = useContainer()
|
|
@@ -90,7 +92,7 @@ export function TldrawUiDropdownMenuContent({
|
|
|
90
92
|
sideOffset={sideOffset}
|
|
91
93
|
align={align}
|
|
92
94
|
alignOffset={alignOffset}
|
|
93
|
-
collisionPadding={
|
|
95
|
+
collisionPadding={collisionPadding}
|
|
94
96
|
>
|
|
95
97
|
{children}
|
|
96
98
|
</_DropdownMenu.Content>
|
|
@@ -11,6 +11,7 @@ export interface TLUiIconProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
11
11
|
icon: TLUiIconType | Exclude<string, TLUiIconType> | TLUiIconJsx
|
|
12
12
|
label: string
|
|
13
13
|
small?: boolean
|
|
14
|
+
tiny?: boolean
|
|
14
15
|
color?: string
|
|
15
16
|
children?: undefined
|
|
16
17
|
invertIcon?: boolean
|
|
@@ -23,6 +24,7 @@ export const TldrawUiIcon = memo(function TldrawUiIcon({
|
|
|
23
24
|
small,
|
|
24
25
|
invertIcon,
|
|
25
26
|
icon,
|
|
27
|
+
tiny,
|
|
26
28
|
color,
|
|
27
29
|
className,
|
|
28
30
|
...props
|
|
@@ -32,6 +34,7 @@ export const TldrawUiIcon = memo(function TldrawUiIcon({
|
|
|
32
34
|
<TldrawUIIconInner
|
|
33
35
|
label={label}
|
|
34
36
|
small={small}
|
|
37
|
+
tiny={tiny}
|
|
35
38
|
invertIcon={invertIcon}
|
|
36
39
|
icon={icon}
|
|
37
40
|
color={color}
|
|
@@ -43,7 +46,11 @@ export const TldrawUiIcon = memo(function TldrawUiIcon({
|
|
|
43
46
|
|
|
44
47
|
return cloneElement(icon, {
|
|
45
48
|
...props,
|
|
46
|
-
className: classNames(
|
|
49
|
+
className: classNames(
|
|
50
|
+
{ 'tlui-icon__small': small, 'tlui-icon__tiny': tiny },
|
|
51
|
+
className,
|
|
52
|
+
icon.props.className
|
|
53
|
+
),
|
|
47
54
|
'aria-label': label,
|
|
48
55
|
style: {
|
|
49
56
|
color,
|
|
@@ -56,6 +63,7 @@ export const TldrawUiIcon = memo(function TldrawUiIcon({
|
|
|
56
63
|
function TldrawUIIconInner({
|
|
57
64
|
label,
|
|
58
65
|
small,
|
|
66
|
+
tiny,
|
|
59
67
|
invertIcon,
|
|
60
68
|
icon,
|
|
61
69
|
color,
|
|
@@ -85,7 +93,7 @@ function TldrawUIIconInner({
|
|
|
85
93
|
<div
|
|
86
94
|
className={classNames(
|
|
87
95
|
'tlui-icon tlui-icon__placeholder',
|
|
88
|
-
{ 'tlui-icon__small': small },
|
|
96
|
+
{ 'tlui-icon__small': small, 'tlui-icon__tiny': tiny },
|
|
89
97
|
className
|
|
90
98
|
)}
|
|
91
99
|
{...props}
|
|
@@ -99,7 +107,11 @@ function TldrawUIIconInner({
|
|
|
99
107
|
ref={ref}
|
|
100
108
|
aria-label={label}
|
|
101
109
|
role="img"
|
|
102
|
-
className={classNames(
|
|
110
|
+
className={classNames(
|
|
111
|
+
'tlui-icon',
|
|
112
|
+
{ 'tlui-icon__small': small, 'tlui-icon__tiny': tiny },
|
|
113
|
+
className
|
|
114
|
+
)}
|
|
103
115
|
style={{
|
|
104
116
|
color,
|
|
105
117
|
mask: `url(${asset}) center 100% / 100% no-repeat`,
|
|
@@ -17,6 +17,8 @@ export interface TLUiInputProps {
|
|
|
17
17
|
autoSelect?: boolean
|
|
18
18
|
children?: React.ReactNode
|
|
19
19
|
defaultValue?: string
|
|
20
|
+
/** Maximum number of characters the input will accept. */
|
|
21
|
+
maxLength?: number
|
|
20
22
|
placeholder?: string
|
|
21
23
|
onComplete?(value: string): void
|
|
22
24
|
onValueChange?(value: string): void
|
|
@@ -50,6 +52,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
50
52
|
autoSelect = false,
|
|
51
53
|
autoFocus = false,
|
|
52
54
|
defaultValue,
|
|
55
|
+
maxLength,
|
|
53
56
|
placeholder,
|
|
54
57
|
onComplete,
|
|
55
58
|
onValueChange,
|
|
@@ -196,6 +199,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
196
199
|
className={classNames('tlui-input', className)}
|
|
197
200
|
type="text"
|
|
198
201
|
defaultValue={defaultValue}
|
|
202
|
+
maxLength={maxLength}
|
|
199
203
|
onKeyDownCapture={handleKeyDownCapture}
|
|
200
204
|
onChange={handleChange}
|
|
201
205
|
onFocus={handleFocus}
|
|
@@ -47,6 +47,11 @@ export interface TLUiPopoverContentProps {
|
|
|
47
47
|
align?: 'start' | 'center' | 'end'
|
|
48
48
|
alignOffset?: number
|
|
49
49
|
sideOffset?: number
|
|
50
|
+
/**
|
|
51
|
+
* Minimum distance to keep between the popover and the viewport edge before it
|
|
52
|
+
* shifts to stay in view. Defaults to Radix's `0`.
|
|
53
|
+
*/
|
|
54
|
+
collisionPadding?: number
|
|
50
55
|
disableEscapeKeyDown?: boolean
|
|
51
56
|
autoFocusFirstButton?: boolean
|
|
52
57
|
}
|
|
@@ -58,6 +63,7 @@ export function TldrawUiPopoverContent({
|
|
|
58
63
|
align = 'center',
|
|
59
64
|
sideOffset = 8,
|
|
60
65
|
alignOffset = 0,
|
|
66
|
+
collisionPadding,
|
|
61
67
|
disableEscapeKeyDown = false,
|
|
62
68
|
autoFocusFirstButton = true,
|
|
63
69
|
}: TLUiPopoverContentProps) {
|
|
@@ -83,6 +89,7 @@ export function TldrawUiPopoverContent({
|
|
|
83
89
|
sideOffset={sideOffset}
|
|
84
90
|
align={align}
|
|
85
91
|
alignOffset={alignOffset}
|
|
92
|
+
collisionPadding={collisionPadding}
|
|
86
93
|
dir={dir}
|
|
87
94
|
ref={ref}
|
|
88
95
|
onOpenAutoFocus={handleOpenAutoFocus}
|
|
@@ -60,7 +60,6 @@ export function TldrawUiMenuCheckboxItem<
|
|
|
60
60
|
dir={dir}
|
|
61
61
|
lang={lang}
|
|
62
62
|
className="tlui-button tlui-button__menu tlui-button__checkbox"
|
|
63
|
-
title={labelStr}
|
|
64
63
|
onSelect={(e) => {
|
|
65
64
|
onSelect?.(sourceId)
|
|
66
65
|
preventDefault(e)
|
|
@@ -89,7 +88,6 @@ export function TldrawUiMenuCheckboxItem<
|
|
|
89
88
|
className="tlui-button tlui-button__menu tlui-button__checkbox"
|
|
90
89
|
dir={dir}
|
|
91
90
|
lang={lang}
|
|
92
|
-
title={labelStr}
|
|
93
91
|
onSelect={(e) => {
|
|
94
92
|
onSelect(sourceId)
|
|
95
93
|
preventDefault(e)
|
|
@@ -50,7 +50,6 @@ export function TldrawUiMenuSubmenu<Translation extends string = string>({
|
|
|
50
50
|
id={`${sourceId}-sub.${id}-button`}
|
|
51
51
|
disabled={disabled}
|
|
52
52
|
label={labelStr!}
|
|
53
|
-
title={labelStr!}
|
|
54
53
|
/>
|
|
55
54
|
<TldrawUiDropdownMenuSubContent id={`${sourceId}-sub.${id}-content`} size={size}>
|
|
56
55
|
{children}
|