tldraw 3.16.0-internal.51e99e128bd4 → 3.16.0-internal.71f83a8a571b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +177 -110
- package/dist-cjs/index.js +29 -14
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/Tldraw.js +12 -2
- package/dist-cjs/lib/Tldraw.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +1 -1
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +8 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/crop.js +1 -0
- package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -4
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
- package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
- package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +13 -12
- package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +1 -1
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
- package/dist-cjs/lib/ui/components/EditLinkDialog.js +11 -1
- package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +62 -36
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +5 -5
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +1 -1
- package/dist-cjs/lib/ui/context/actions.js +23 -10
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/components.js +2 -0
- package/dist-cjs/lib/ui/context/components.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.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 +4 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/kbd-utils.js +9 -3
- package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +1 -1
- package/dist-cjs/lib/utils/export/copyAs.js +1 -2
- package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
- package/dist-cjs/lib/utils/export/export.js +0 -20
- package/dist-cjs/lib/utils/export/export.js.map +2 -2
- package/dist-cjs/lib/utils/export/exportAs.js +1 -2
- package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
- package/dist-esm/index.d.mts +177 -110
- package/dist-esm/index.mjs +57 -29
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/Tldraw.mjs +14 -4
- package/dist-esm/lib/Tldraw.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +1 -1
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +5 -5
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +8 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +3 -3
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/crop.mjs +1 -0
- package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +4 -5
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -3
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
- package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
- package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs +11 -1
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +12 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +3 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +63 -36
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +5 -5
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +1 -1
- package/dist-esm/lib/ui/context/actions.mjs +23 -10
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/components.mjs +2 -0
- package/dist-esm/lib/ui/context/components.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +1 -1
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
- package/dist-esm/lib/ui/hooks/useExportAs.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 +4 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
- package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +1 -1
- package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
- package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
- package/dist-esm/lib/utils/export/export.mjs +0 -20
- package/dist-esm/lib/utils/export/export.mjs.map +2 -2
- package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
- package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
- package/package.json +3 -3
- package/src/index.ts +41 -22
- package/src/lib/Tldraw.tsx +15 -2
- package/src/lib/defaultExternalContentHandlers.ts +12 -4
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +2 -2
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +41 -0
- package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
- package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
- package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +2 -2
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +5 -5
- package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +9 -0
- package/src/lib/shapes/frame/components/FrameLabelInput.tsx +3 -3
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
- package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -4
- package/src/lib/shapes/note/NoteShapeTool.test.ts +2 -1
- package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
- package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
- package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -7
- package/src/lib/shapes/shared/RichTextLabel.tsx +2 -1
- package/src/lib/shapes/shared/crop.ts +1 -0
- package/src/lib/shapes/shared/useEditablePlainText.ts +12 -12
- package/src/lib/shapes/shared/useEditableRichText.ts +7 -3
- package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
- package/src/lib/shapes/text/PlainTextArea.tsx +3 -3
- package/src/lib/shapes/text/RichTextArea.tsx +3 -4
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +1 -1
- package/src/lib/ui/TldrawUi.tsx +16 -10
- package/src/lib/ui/components/A11y.tsx +2 -2
- package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
- package/src/lib/ui/components/EditLinkDialog.tsx +16 -6
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +2 -2
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
- package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
- package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
- package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
- package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
- package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +5 -4
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
- package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
- package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +8 -3
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +3 -3
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -0
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +67 -29
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +6 -6
- package/src/lib/ui/context/actions.tsx +23 -10
- package/src/lib/ui/context/components.tsx +3 -0
- package/src/lib/ui/context/events.tsx +1 -1
- package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
- package/src/lib/ui/hooks/useExportAs.ts +3 -2
- package/src/lib/ui/hooks/useTools.tsx +1 -1
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -2
- package/src/lib/ui/kbd-utils.ts +10 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +19 -2
- package/src/lib/utils/excalidraw/putExcalidrawContent.ts +6 -6
- package/src/lib/utils/export/copyAs.ts +1 -24
- package/src/lib/utils/export/export.ts +0 -36
- package/src/lib/utils/export/exportAs.ts +1 -32
- package/src/test/Editor.test.tsx +37 -10
- package/src/test/TldrawEditor.test.tsx +15 -9
- package/src/test/commands/putContent.test.ts +1 -0
- package/src/test/commands/updateShapes.test.ts +9 -5
- package/src/test/custom-clipping.test.ts +442 -0
- package/src/test/customSnapping.test.tsx +55 -41
- package/src/test/getCulledShapes.test.tsx +77 -2
- package/src/test/groups.test.tsx +4 -2
- package/src/test/translating.test.ts +2 -2
- package/tldraw.css +35 -5
- package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
- package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import {
|
|
2
|
+
atom,
|
|
3
|
+
BaseBoxShapeUtil,
|
|
4
|
+
Circle2d,
|
|
5
|
+
createShapeId,
|
|
6
|
+
Geometry2d,
|
|
7
|
+
RecordProps,
|
|
8
|
+
resizeBox,
|
|
9
|
+
StateNode,
|
|
10
|
+
T,
|
|
11
|
+
TLBaseShape,
|
|
12
|
+
TLEventHandlers,
|
|
13
|
+
TLGeoShape,
|
|
14
|
+
TLResizeInfo,
|
|
15
|
+
TLShape,
|
|
16
|
+
TLTextShape,
|
|
17
|
+
toRichText,
|
|
18
|
+
Vec,
|
|
19
|
+
} from '@tldraw/editor'
|
|
20
|
+
import { TestEditor } from './TestEditor'
|
|
21
|
+
|
|
22
|
+
declare module '@tldraw/tlschema' {
|
|
23
|
+
export interface GlobalShapePropsMap {
|
|
24
|
+
'circle-clip': CircleClipShape
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Custom Circle Clip Shape Definition
|
|
29
|
+
export type CircleClipShape = TLBaseShape<
|
|
30
|
+
'circle-clip',
|
|
31
|
+
{
|
|
32
|
+
w: number
|
|
33
|
+
h: number
|
|
34
|
+
}
|
|
35
|
+
>
|
|
36
|
+
|
|
37
|
+
export const isClippingEnabled$ = atom('isClippingEnabled', true)
|
|
38
|
+
|
|
39
|
+
export class CircleClipShapeUtil extends BaseBoxShapeUtil<CircleClipShape> {
|
|
40
|
+
static override type = 'circle-clip' as const
|
|
41
|
+
static override props: RecordProps<CircleClipShape> = {
|
|
42
|
+
w: T.number,
|
|
43
|
+
h: T.number,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override canBind() {
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override canReceiveNewChildrenOfType(shape: TLShape) {
|
|
51
|
+
return !shape.isLocked
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override getDefaultProps(): CircleClipShape['props'] {
|
|
55
|
+
return {
|
|
56
|
+
w: 200,
|
|
57
|
+
h: 200,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override getGeometry(shape: CircleClipShape): Geometry2d {
|
|
62
|
+
const radius = Math.min(shape.props.w, shape.props.h) / 2
|
|
63
|
+
return new Circle2d({
|
|
64
|
+
radius,
|
|
65
|
+
x: shape.props.w / 2 - radius,
|
|
66
|
+
y: shape.props.h / 2 - radius,
|
|
67
|
+
isFilled: true,
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override getClipPath(shape: CircleClipShape): Vec[] | undefined {
|
|
72
|
+
// Generate a polygon approximation of the circle
|
|
73
|
+
const centerX = shape.props.w / 2
|
|
74
|
+
const centerY = shape.props.h / 2
|
|
75
|
+
const radius = Math.min(shape.props.w, shape.props.h) / 2
|
|
76
|
+
const segments = 48 // More segments = smoother circle
|
|
77
|
+
|
|
78
|
+
const points: Vec[] = []
|
|
79
|
+
for (let i = 0; i < segments; i++) {
|
|
80
|
+
const angle = (i / segments) * Math.PI * 2
|
|
81
|
+
const x = centerX + Math.cos(angle) * radius
|
|
82
|
+
const y = centerY + Math.sin(angle) * radius
|
|
83
|
+
points.push(new Vec(x, y))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return points
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
override shouldClipChild(_child: TLShape): boolean {
|
|
90
|
+
// For now, clip all children - we removed the onlyClipText feature for simplicity
|
|
91
|
+
return isClippingEnabled$.get()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override component(_shape: CircleClipShape) {
|
|
95
|
+
// For testing purposes, we'll just return null
|
|
96
|
+
// In a real implementation, this would return JSX
|
|
97
|
+
return null as any
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override indicator(_shape: CircleClipShape) {
|
|
101
|
+
// For testing purposes, we'll just return null
|
|
102
|
+
// In a real implementation, this would return JSX
|
|
103
|
+
return null as any
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override onResize(shape: CircleClipShape, info: TLResizeInfo<CircleClipShape>) {
|
|
107
|
+
return resizeBox(shape, info)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export class CircleClipShapeTool extends StateNode {
|
|
112
|
+
static override id = 'circle-clip'
|
|
113
|
+
|
|
114
|
+
override onEnter(): void {
|
|
115
|
+
this.editor.setCursor({ type: 'cross', rotation: 0 })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
override onPointerDown(info: Parameters<TLEventHandlers['onPointerDown']>[0]) {
|
|
119
|
+
if (info.target === 'canvas') {
|
|
120
|
+
const { originPagePoint } = this.editor.inputs
|
|
121
|
+
|
|
122
|
+
this.editor.createShape<CircleClipShape>({
|
|
123
|
+
type: 'circle-clip',
|
|
124
|
+
x: originPagePoint.x - 100,
|
|
125
|
+
y: originPagePoint.y - 100,
|
|
126
|
+
props: {
|
|
127
|
+
w: 200,
|
|
128
|
+
h: 200,
|
|
129
|
+
},
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let editor: TestEditor
|
|
136
|
+
|
|
137
|
+
afterEach(() => {
|
|
138
|
+
editor?.dispose()
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const ids = {
|
|
142
|
+
circleClip1: createShapeId('circleClip1'),
|
|
143
|
+
circleClip2: createShapeId('circleClip2'),
|
|
144
|
+
text1: createShapeId('text1'),
|
|
145
|
+
geo1: createShapeId('geo1'),
|
|
146
|
+
geo2: createShapeId('geo2'),
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
beforeEach(() => {
|
|
150
|
+
editor = new TestEditor({
|
|
151
|
+
shapeUtils: [CircleClipShapeUtil],
|
|
152
|
+
tools: [CircleClipShapeTool],
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
// Reset clipping state
|
|
156
|
+
isClippingEnabled$.set(true)
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
describe('CircleClipShapeUtil', () => {
|
|
160
|
+
describe('shape creation and properties', () => {
|
|
161
|
+
it('should create a circle clip shape with default properties', () => {
|
|
162
|
+
editor.createShape<CircleClipShape>({
|
|
163
|
+
id: ids.circleClip1,
|
|
164
|
+
type: 'circle-clip',
|
|
165
|
+
x: 100,
|
|
166
|
+
y: 100,
|
|
167
|
+
props: {
|
|
168
|
+
w: 200,
|
|
169
|
+
h: 200,
|
|
170
|
+
},
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
|
|
174
|
+
expect(shape).toBeDefined()
|
|
175
|
+
expect(shape!.type).toBe('circle-clip')
|
|
176
|
+
expect(shape!.props.w).toBe(200)
|
|
177
|
+
expect(shape!.props.h).toBe(200)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('should use default props when not specified', () => {
|
|
181
|
+
editor.createShape<CircleClipShape>({
|
|
182
|
+
id: ids.circleClip1,
|
|
183
|
+
type: 'circle-clip',
|
|
184
|
+
x: 100,
|
|
185
|
+
y: 100,
|
|
186
|
+
props: {},
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
|
|
190
|
+
expect(shape!.props.w).toBe(200) // default from getDefaultProps
|
|
191
|
+
expect(shape!.props.h).toBe(200) // default from getDefaultProps
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
describe('geometry and clipping', () => {
|
|
196
|
+
it('should generate correct circle geometry', () => {
|
|
197
|
+
editor.createShape<CircleClipShape>({
|
|
198
|
+
id: ids.circleClip1,
|
|
199
|
+
type: 'circle-clip',
|
|
200
|
+
x: 100,
|
|
201
|
+
y: 100,
|
|
202
|
+
props: {
|
|
203
|
+
w: 200,
|
|
204
|
+
h: 200,
|
|
205
|
+
},
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
|
|
209
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
210
|
+
const geometry = util.getGeometry(shape!)
|
|
211
|
+
|
|
212
|
+
expect(geometry).toBeDefined()
|
|
213
|
+
expect(geometry.bounds).toBeDefined()
|
|
214
|
+
expect(geometry.bounds.width).toBe(200)
|
|
215
|
+
expect(geometry.bounds.height).toBe(200)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('should generate clip path for circle', () => {
|
|
219
|
+
editor.createShape<CircleClipShape>({
|
|
220
|
+
id: ids.circleClip1,
|
|
221
|
+
type: 'circle-clip',
|
|
222
|
+
x: 100,
|
|
223
|
+
y: 100,
|
|
224
|
+
props: {
|
|
225
|
+
w: 200,
|
|
226
|
+
h: 200,
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
|
|
231
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
232
|
+
const clipPath = util.getClipPath?.(shape!)
|
|
233
|
+
if (!clipPath) throw new Error('Clip path is undefined')
|
|
234
|
+
|
|
235
|
+
expect(clipPath).toBeDefined()
|
|
236
|
+
expect(Array.isArray(clipPath)).toBe(true)
|
|
237
|
+
expect(clipPath.length).toBeGreaterThan(0)
|
|
238
|
+
|
|
239
|
+
// Should be a polygon approximation of a circle
|
|
240
|
+
// Check that points are roughly in a circle pattern
|
|
241
|
+
const centerX = 100 // shape.x
|
|
242
|
+
const centerY = 100 // shape.y
|
|
243
|
+
const radius = 100 // min(w, h) / 2
|
|
244
|
+
|
|
245
|
+
clipPath.forEach((point) => {
|
|
246
|
+
const distance = Math.sqrt(Math.pow(point.x - centerX, 2) + Math.pow(point.y - centerY, 2))
|
|
247
|
+
expect(distance).toBeCloseTo(radius, 0)
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
describe('child clipping behavior', () => {
|
|
253
|
+
it('should clip children when clipping is enabled', () => {
|
|
254
|
+
editor.createShape<CircleClipShape>({
|
|
255
|
+
id: ids.circleClip1,
|
|
256
|
+
type: 'circle-clip',
|
|
257
|
+
x: 100,
|
|
258
|
+
y: 100,
|
|
259
|
+
props: {
|
|
260
|
+
w: 200,
|
|
261
|
+
h: 200,
|
|
262
|
+
},
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
editor.createShape<TLTextShape>({
|
|
266
|
+
id: ids.text1,
|
|
267
|
+
type: 'text',
|
|
268
|
+
x: 0,
|
|
269
|
+
y: 0,
|
|
270
|
+
parentId: ids.circleClip1,
|
|
271
|
+
props: {
|
|
272
|
+
richText: toRichText('Test text'),
|
|
273
|
+
},
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
277
|
+
const textShape = editor.getShape<TLTextShape>(ids.text1)
|
|
278
|
+
|
|
279
|
+
// Clipping should be enabled by default
|
|
280
|
+
expect(isClippingEnabled$.get()).toBe(true)
|
|
281
|
+
expect(util.shouldClipChild?.(textShape!)).toBe(true)
|
|
282
|
+
expect(editor.getShapeClipPath(ids.text1)).toBeDefined()
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
it('should not clip children when clipping is disabled', () => {
|
|
286
|
+
isClippingEnabled$.set(false)
|
|
287
|
+
|
|
288
|
+
editor.createShape<CircleClipShape>({
|
|
289
|
+
id: ids.circleClip1,
|
|
290
|
+
type: 'circle-clip',
|
|
291
|
+
x: 100,
|
|
292
|
+
y: 100,
|
|
293
|
+
props: {
|
|
294
|
+
w: 200,
|
|
295
|
+
h: 200,
|
|
296
|
+
},
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
editor.createShape<TLTextShape>({
|
|
300
|
+
id: ids.text1,
|
|
301
|
+
type: 'text',
|
|
302
|
+
x: 0,
|
|
303
|
+
y: 0,
|
|
304
|
+
parentId: ids.circleClip1,
|
|
305
|
+
props: {
|
|
306
|
+
richText: toRichText('Test text'),
|
|
307
|
+
},
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
311
|
+
const textShape = editor.getShape<TLTextShape>(ids.text1)
|
|
312
|
+
|
|
313
|
+
expect(isClippingEnabled$.get()).toBe(false)
|
|
314
|
+
expect(util.shouldClipChild?.(textShape!)).toBe(false)
|
|
315
|
+
expect(editor.getShapeClipPath(ids.text1)).toBeUndefined()
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
describe('Integration tests', () => {
|
|
321
|
+
it('should create and manage circle clip shapes with children', () => {
|
|
322
|
+
// Create circle clip shape
|
|
323
|
+
editor.createShape<CircleClipShape>({
|
|
324
|
+
id: ids.circleClip1,
|
|
325
|
+
type: 'circle-clip',
|
|
326
|
+
x: 100,
|
|
327
|
+
y: 100,
|
|
328
|
+
props: {
|
|
329
|
+
w: 200,
|
|
330
|
+
h: 200,
|
|
331
|
+
},
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
// Add text child
|
|
335
|
+
editor.createShape<TLTextShape>({
|
|
336
|
+
id: ids.text1,
|
|
337
|
+
type: 'text',
|
|
338
|
+
x: 50,
|
|
339
|
+
y: 50,
|
|
340
|
+
parentId: ids.circleClip1,
|
|
341
|
+
props: {
|
|
342
|
+
richText: toRichText('Clipped text'),
|
|
343
|
+
},
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
// Add geo child
|
|
347
|
+
editor.createShape<TLGeoShape>({
|
|
348
|
+
id: ids.geo1,
|
|
349
|
+
type: 'geo',
|
|
350
|
+
x: 150,
|
|
351
|
+
y: 150,
|
|
352
|
+
parentId: ids.circleClip1,
|
|
353
|
+
props: {
|
|
354
|
+
w: 50,
|
|
355
|
+
h: 50,
|
|
356
|
+
},
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
const circleClipShape = editor.getShape<CircleClipShape>(ids.circleClip1)
|
|
360
|
+
const textShape = editor.getShape<TLTextShape>(ids.text1)
|
|
361
|
+
const geoShape = editor.getShape<TLGeoShape>(ids.geo1)
|
|
362
|
+
|
|
363
|
+
expect(circleClipShape).toBeDefined()
|
|
364
|
+
expect(textShape!.parentId).toBe(ids.circleClip1)
|
|
365
|
+
expect(geoShape!.parentId).toBe(ids.circleClip1)
|
|
366
|
+
|
|
367
|
+
// Verify clipping behavior
|
|
368
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
369
|
+
expect(util.shouldClipChild?.(textShape!)).toBe(true)
|
|
370
|
+
expect(util.shouldClipChild?.(geoShape!)).toBe(true)
|
|
371
|
+
expect(editor.getShapeClipPath(ids.text1)).toBeDefined()
|
|
372
|
+
expect(editor.getShapeClipPath(ids.geo1)).toBeDefined()
|
|
373
|
+
|
|
374
|
+
// Test clipping toggle
|
|
375
|
+
isClippingEnabled$.set(false)
|
|
376
|
+
expect(util.shouldClipChild?.(textShape!)).toBe(false)
|
|
377
|
+
expect(util.shouldClipChild?.(geoShape!)).toBe(false)
|
|
378
|
+
expect(editor.getShapeClipPath(ids.text1)).toBeUndefined()
|
|
379
|
+
expect(editor.getShapeClipPath(ids.geo1)).toBeUndefined()
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('should handle multiple circle clip shapes independently', () => {
|
|
383
|
+
// Create two circle clip shapes
|
|
384
|
+
editor.createShape<CircleClipShape>({
|
|
385
|
+
id: ids.circleClip1,
|
|
386
|
+
type: 'circle-clip',
|
|
387
|
+
x: 100,
|
|
388
|
+
y: 100,
|
|
389
|
+
props: {
|
|
390
|
+
w: 200,
|
|
391
|
+
h: 200,
|
|
392
|
+
},
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
editor.createShape<CircleClipShape>({
|
|
396
|
+
id: ids.circleClip2,
|
|
397
|
+
type: 'circle-clip',
|
|
398
|
+
x: 400,
|
|
399
|
+
y: 100,
|
|
400
|
+
props: {
|
|
401
|
+
w: 150,
|
|
402
|
+
h: 150,
|
|
403
|
+
},
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
// Add children to both
|
|
407
|
+
editor.createShape<TLTextShape>({
|
|
408
|
+
id: ids.text1,
|
|
409
|
+
type: 'text',
|
|
410
|
+
x: 0,
|
|
411
|
+
y: 0,
|
|
412
|
+
parentId: ids.circleClip1,
|
|
413
|
+
props: {
|
|
414
|
+
richText: toRichText('First clip'),
|
|
415
|
+
},
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
editor.createShape<TLTextShape>({
|
|
419
|
+
id: ids.geo1,
|
|
420
|
+
type: 'text',
|
|
421
|
+
x: 0,
|
|
422
|
+
y: 0,
|
|
423
|
+
parentId: ids.circleClip2,
|
|
424
|
+
props: {
|
|
425
|
+
richText: toRichText('Second clip'),
|
|
426
|
+
},
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
|
|
430
|
+
const text1 = editor.getShape<TLTextShape>(ids.text1)
|
|
431
|
+
const text2 = editor.getShape<TLTextShape>(ids.geo1)
|
|
432
|
+
|
|
433
|
+
// Both should be clipped when enabled
|
|
434
|
+
expect(util.shouldClipChild?.(text1!)).toBe(true)
|
|
435
|
+
expect(util.shouldClipChild?.(text2!)).toBe(true)
|
|
436
|
+
|
|
437
|
+
// Both should not be clipped when disabled
|
|
438
|
+
isClippingEnabled$.set(false)
|
|
439
|
+
expect(util.shouldClipChild?.(text1!)).toBe(false)
|
|
440
|
+
expect(util.shouldClipChild?.(text2!)).toBe(false)
|
|
441
|
+
})
|
|
442
|
+
})
|
|
@@ -15,13 +15,20 @@ import {
|
|
|
15
15
|
import { TestEditor } from './TestEditor'
|
|
16
16
|
import { TL } from './test-jsx'
|
|
17
17
|
|
|
18
|
+
declare module '@tldraw/tlschema' {
|
|
19
|
+
export interface GlobalShapePropsMap {
|
|
20
|
+
test1: Test1Shape
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type Test1Shape = TLBaseShape<
|
|
25
|
+
'test1',
|
|
26
|
+
{ w: number; h: number; boundsSnapPoints: VecModel[] | null }
|
|
27
|
+
>
|
|
28
|
+
|
|
18
29
|
describe('custom shape bounds snapping - translate', () => {
|
|
19
|
-
|
|
20
|
-
'
|
|
21
|
-
{ w: number; h: number; boundsSnapPoints: VecModel[] | null }
|
|
22
|
-
>
|
|
23
|
-
class TestShapeUtil extends BaseBoxShapeUtil<TestShape> {
|
|
24
|
-
static override type = 'test'
|
|
30
|
+
class TestShapeUtil extends BaseBoxShapeUtil<Test1Shape> {
|
|
31
|
+
static override type = 'test1'
|
|
25
32
|
override getDefaultProps() {
|
|
26
33
|
return { w: 100, h: 100, boundsSnapPoints: null }
|
|
27
34
|
}
|
|
@@ -31,7 +38,7 @@ describe('custom shape bounds snapping - translate', () => {
|
|
|
31
38
|
override indicator() {
|
|
32
39
|
throw new Error('Method not implemented.')
|
|
33
40
|
}
|
|
34
|
-
override getBoundsSnapGeometry(shape:
|
|
41
|
+
override getBoundsSnapGeometry(shape: Test1Shape) {
|
|
35
42
|
return {
|
|
36
43
|
points: shape.props.boundsSnapPoints ?? undefined,
|
|
37
44
|
}
|
|
@@ -83,9 +90,9 @@ describe('custom shape bounds snapping - translate', () => {
|
|
|
83
90
|
|
|
84
91
|
describe('with only the center in boundSnapPoints', () => {
|
|
85
92
|
beforeEach(() => {
|
|
86
|
-
editor.updateShape<
|
|
93
|
+
editor.updateShape<Test1Shape>({
|
|
87
94
|
id: ids.test,
|
|
88
|
-
type: '
|
|
95
|
+
type: 'test1',
|
|
89
96
|
props: { boundsSnapPoints: [{ x: 50, y: 50 }] },
|
|
90
97
|
})
|
|
91
98
|
})
|
|
@@ -125,9 +132,9 @@ describe('custom shape bounds snapping - translate', () => {
|
|
|
125
132
|
|
|
126
133
|
describe('with empty boundSnapPoints', () => {
|
|
127
134
|
beforeEach(() => {
|
|
128
|
-
editor.updateShape<
|
|
135
|
+
editor.updateShape<Test1Shape>({
|
|
129
136
|
id: ids.test,
|
|
130
|
-
type: '
|
|
137
|
+
type: 'test1',
|
|
131
138
|
props: { boundsSnapPoints: [] },
|
|
132
139
|
})
|
|
133
140
|
})
|
|
@@ -162,22 +169,29 @@ describe('custom shape bounds snapping - translate', () => {
|
|
|
162
169
|
})
|
|
163
170
|
})
|
|
164
171
|
|
|
172
|
+
declare module '@tldraw/tlschema' {
|
|
173
|
+
export interface GlobalShapePropsMap {
|
|
174
|
+
test2: Test2Shape
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
type Test2Shape = TLBaseShape<
|
|
179
|
+
'test2',
|
|
180
|
+
{
|
|
181
|
+
w: number
|
|
182
|
+
h: number
|
|
183
|
+
ownHandle: VecModel
|
|
184
|
+
handleOutline: VecModel[] | 'default' | null
|
|
185
|
+
handlePoints: VecModel[] | 'default'
|
|
186
|
+
selfSnapOutline: VecModel[] | 'default'
|
|
187
|
+
selfSnapPoints: VecModel[] | 'default'
|
|
188
|
+
}
|
|
189
|
+
>
|
|
190
|
+
|
|
165
191
|
describe('custom handle snapping', () => {
|
|
166
|
-
|
|
167
|
-
'
|
|
168
|
-
{
|
|
169
|
-
w: number
|
|
170
|
-
h: number
|
|
171
|
-
ownHandle: VecModel
|
|
172
|
-
handleOutline: VecModel[] | 'default' | null
|
|
173
|
-
handlePoints: VecModel[] | 'default'
|
|
174
|
-
selfSnapOutline: VecModel[] | 'default'
|
|
175
|
-
selfSnapPoints: VecModel[] | 'default'
|
|
176
|
-
}
|
|
177
|
-
>
|
|
178
|
-
class TestShapeUtil extends BaseBoxShapeUtil<TestShape> {
|
|
179
|
-
static override type = 'test'
|
|
180
|
-
override getDefaultProps(): TestShape['props'] {
|
|
192
|
+
class TestShapeUtil extends BaseBoxShapeUtil<Test2Shape> {
|
|
193
|
+
static override type = 'test2'
|
|
194
|
+
override getDefaultProps(): Test2Shape['props'] {
|
|
181
195
|
return {
|
|
182
196
|
w: 100,
|
|
183
197
|
h: 100,
|
|
@@ -194,7 +208,7 @@ describe('custom handle snapping', () => {
|
|
|
194
208
|
override indicator() {
|
|
195
209
|
throw new Error('Method not implemented.')
|
|
196
210
|
}
|
|
197
|
-
override getHandleSnapGeometry(shape:
|
|
211
|
+
override getHandleSnapGeometry(shape: Test2Shape) {
|
|
198
212
|
const { handleOutline, handlePoints, selfSnapOutline, selfSnapPoints } = shape.props
|
|
199
213
|
return {
|
|
200
214
|
outline:
|
|
@@ -212,7 +226,7 @@ describe('custom handle snapping', () => {
|
|
|
212
226
|
getSelfSnapPoints: selfSnapPoints === 'default' ? undefined : () => selfSnapPoints,
|
|
213
227
|
}
|
|
214
228
|
}
|
|
215
|
-
override getHandles(shape:
|
|
229
|
+
override getHandles(shape: Test2Shape): TLHandle[] {
|
|
216
230
|
return [
|
|
217
231
|
{
|
|
218
232
|
id: 'handle',
|
|
@@ -225,7 +239,7 @@ describe('custom handle snapping', () => {
|
|
|
225
239
|
},
|
|
226
240
|
]
|
|
227
241
|
}
|
|
228
|
-
override onHandleDrag(shape:
|
|
242
|
+
override onHandleDrag(shape: Test2Shape, { handle }: TLHandleDragInfo<Test2Shape>) {
|
|
229
243
|
return { ...shape, props: { ...shape.props, ownHandle: { x: handle.x, y: handle.y } } }
|
|
230
244
|
}
|
|
231
245
|
}
|
|
@@ -288,9 +302,9 @@ describe('custom handle snapping', () => {
|
|
|
288
302
|
|
|
289
303
|
describe('with empty handleSnapGeometry.outline', () => {
|
|
290
304
|
beforeEach(() => {
|
|
291
|
-
editor.updateShape<
|
|
305
|
+
editor.updateShape<Test2Shape>({
|
|
292
306
|
id: ids.test,
|
|
293
|
-
type: '
|
|
307
|
+
type: 'test2',
|
|
294
308
|
props: { handleOutline: null },
|
|
295
309
|
})
|
|
296
310
|
})
|
|
@@ -305,9 +319,9 @@ describe('custom handle snapping', () => {
|
|
|
305
319
|
|
|
306
320
|
describe('with custom handleSnapGeometry.outline', () => {
|
|
307
321
|
beforeEach(() => {
|
|
308
|
-
editor.updateShape<
|
|
322
|
+
editor.updateShape<Test2Shape>({
|
|
309
323
|
id: ids.test,
|
|
310
|
-
type: '
|
|
324
|
+
type: 'test2',
|
|
311
325
|
props: {
|
|
312
326
|
// a diagonal line from the top left to the bottom right
|
|
313
327
|
handleOutline: [
|
|
@@ -352,9 +366,9 @@ describe('custom handle snapping', () => {
|
|
|
352
366
|
|
|
353
367
|
describe('with custom handleSnapGeometry.points', () => {
|
|
354
368
|
beforeEach(() => {
|
|
355
|
-
editor.updateShape<
|
|
369
|
+
editor.updateShape<Test2Shape>({
|
|
356
370
|
id: ids.test,
|
|
357
|
-
type: '
|
|
371
|
+
type: 'test2',
|
|
358
372
|
props: {
|
|
359
373
|
handlePoints: [
|
|
360
374
|
{ x: 30, y: 30 },
|
|
@@ -379,9 +393,9 @@ describe('custom handle snapping', () => {
|
|
|
379
393
|
|
|
380
394
|
describe('with custom handleSnapGeometry.points along the outline', () => {
|
|
381
395
|
beforeEach(() => {
|
|
382
|
-
editor.updateShape<
|
|
396
|
+
editor.updateShape<Test2Shape>({
|
|
383
397
|
id: ids.test,
|
|
384
|
-
type: '
|
|
398
|
+
type: 'test2',
|
|
385
399
|
props: {
|
|
386
400
|
handlePoints: editor
|
|
387
401
|
.getShapeGeometry(ids.test)
|
|
@@ -418,9 +432,9 @@ describe('custom handle snapping', () => {
|
|
|
418
432
|
describe('self snapping', () => {
|
|
419
433
|
beforeEach(() => {
|
|
420
434
|
editor.deleteShape(ids.line)
|
|
421
|
-
editor.updateShape<
|
|
435
|
+
editor.updateShape<Test2Shape>({
|
|
422
436
|
id: ids.test,
|
|
423
|
-
type: '
|
|
437
|
+
type: 'test2',
|
|
424
438
|
x: 0,
|
|
425
439
|
y: 0,
|
|
426
440
|
props: {
|
|
@@ -454,9 +468,9 @@ describe('custom handle snapping', () => {
|
|
|
454
468
|
})
|
|
455
469
|
describe('with custom self snap outline & points', () => {
|
|
456
470
|
beforeEach(() => {
|
|
457
|
-
editor.updateShape<
|
|
471
|
+
editor.updateShape<Test2Shape>({
|
|
458
472
|
id: ids.test,
|
|
459
|
-
type: '
|
|
473
|
+
type: 'test2',
|
|
460
474
|
props: {
|
|
461
475
|
selfSnapOutline: [
|
|
462
476
|
{ x: 20, y: 50 },
|