tldraw 3.16.0-next.f9f54ec051f3 → 3.16.0-next.fe14f1b4181f
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 +222 -6
- package/dist-cjs/index.js +22 -1
- 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/canvas/TldrawScribble.js +1 -1
- package/dist-cjs/lib/canvas/TldrawScribble.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/ArrowShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +15 -12
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
- package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
- package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +27 -12
- package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
- package/dist-cjs/lib/ui/assetUrls.js +13 -10
- package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.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/DefaultMenuPanel.js +3 -2
- package/dist-cjs/lib/ui/components/DefaultMenuPanel.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/MainMenu/DefaultMainMenuContent.js +3 -3
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
- package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +6 -0
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +6 -4
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +262 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
- package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
- package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -20
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
- package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +31 -2
- 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 +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
- 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 -0
- 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-esm/index.d.mts +222 -6
- package/dist-esm/index.mjs +35 -2
- 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/canvas/TldrawScribble.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawScribble.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/ArrowShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +16 -12
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
- package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
- package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
- package/dist-esm/lib/ui/assetUrls.mjs +13 -10
- package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.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/DefaultMenuPanel.mjs +3 -2
- package/dist-esm/lib/ui/components/DefaultMenuPanel.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/MainMenu/DefaultMainMenuContent.mjs +3 -5
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -140
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +6 -0
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +6 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +30 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +239 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
- package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
- package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -22
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
- package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +31 -2
- 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 +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -0
- 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/package.json +11 -34
- package/src/index.ts +26 -1
- package/src/lib/Tldraw.tsx +15 -2
- package/src/lib/canvas/TldrawScribble.tsx +1 -1
- package/src/lib/defaultExternalContentHandlers.ts +12 -4
- package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
- package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
- package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +25 -14
- package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
- package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
- package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
- package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
- package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
- package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
- package/src/lib/shapes/shared/freehand/svg.ts +2 -0
- package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
- package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
- package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
- package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
- package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
- package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
- package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
- package/src/lib/ui/TldrawUi.tsx +33 -12
- package/src/lib/ui/assetUrls.ts +13 -10
- package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
- package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
- package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
- package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
- package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
- package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
- package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
- package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
- package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
- package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
- package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +14 -11
- package/src/lib/ui/components/menu-items.tsx +8 -0
- package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +35 -30
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +325 -0
- package/src/lib/ui/components/primitives/layout.tsx +107 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -19
- package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
- package/src/lib/ui/context/actions.tsx +31 -2
- package/src/lib/ui/context/components.tsx +3 -0
- package/src/lib/ui/context/events.tsx +2 -0
- package/src/lib/ui/hooks/useTools.tsx +140 -10
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +4 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -0
- package/src/lib/ui/kbd-utils.ts +10 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +409 -292
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
- package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
- package/src/test/A11y.test.tsx +3 -2
- package/src/test/ClickManager.test.ts +7 -6
- package/src/test/Editor.test.tsx +20 -19
- package/src/test/EraserTool.test.ts +184 -13
- package/src/test/HandTool.test.ts +10 -9
- package/src/test/HighlightShape.test.ts +2 -1
- package/src/test/SelectTool.test.ts +3 -2
- package/src/test/TLUserPreferences.test.ts +4 -3
- package/src/test/TestEditor.ts +13 -15
- package/src/test/TldrawEditor.test.tsx +11 -10
- package/src/test/ZoomTool.test.ts +7 -6
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
- package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
- package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
- package/src/test/arrows-megabus.test.tsx +17 -10
- package/src/test/bindings.test.tsx +24 -37
- package/src/test/bookmark-shapes.test.ts +1 -8
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
- package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
- package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
- package/src/test/commands/alignShapes.test.tsx +25 -24
- package/src/test/commands/animationSpeed.test.ts +2 -1
- package/src/test/commands/centerOnPoint.test.ts +3 -2
- package/src/test/commands/clipboard.test.ts +3 -2
- package/src/test/commands/createShapes.test.ts +2 -1
- package/src/test/commands/deleteShapes.test.ts +2 -1
- package/src/test/commands/distributeShapes.test.tsx +11 -10
- package/src/test/commands/getSvgString.test.ts +2 -1
- package/src/test/commands/packShapes.test.ts +5 -4
- package/src/test/commands/resizeShape.test.ts +2 -1
- package/src/test/commands/rotateShapes.test.ts +7 -6
- package/src/test/commands/setCamera.test.ts +4 -3
- package/src/test/commands/setCurrentPage.test.ts +3 -2
- package/src/test/commands/stackShapes.test.ts +11 -10
- package/src/test/commands/stretch.test.tsx +13 -12
- package/src/test/createDeepLink.test.tsx +2 -1
- package/src/test/cropping.test.ts +3 -2
- package/src/test/drawing.test.ts +2 -1
- package/src/test/flipShapes.test.ts +4 -3
- package/src/test/frames.test.ts +25 -24
- package/src/test/getCulledShapes.test.tsx +3 -2
- package/src/test/groups.test.tsx +1 -1
- package/src/test/handleDeepLink.test.tsx +2 -1
- package/src/test/inner-outer-margin.test.ts +315 -0
- package/src/test/maxShapes.test.ts +3 -2
- package/src/test/modifiers.test.ts +5 -4
- package/src/test/navigation.test.ts +12 -11
- package/src/test/panning.test.ts +2 -1
- package/src/test/perf/perf.test.ts +2 -1
- package/src/test/registerDeepLinkListener.test.tsx +10 -9
- package/src/test/resizing.test.ts +39 -38
- package/src/test/select.test.tsx +4 -3
- package/src/test/selection-omnibus.test.ts +11 -10
- package/src/test/shapeutils.test.ts +4 -3
- package/src/test/translating.test.ts +9 -8
- package/tldraw.css +710 -580
- package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
- package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/arrow/arrowTargetState.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tArrowShapeKindStyle,\n\tatom,\n\tAtom,\n\tBox,\n\tclamp,\n\tEditor,\n\tElbowArrowSnap,\n\tGeometry2dFilters,\n\tinvLerp,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n\tobjectMapKeys,\n\tTLArrowBinding,\n\tTLArrowShape,\n\tTLArrowShapeKind,\n\tTLShape,\n\tVec,\n\tVecLike,\n\tWeakCache,\n} from '@tldraw/editor'\nimport { ArrowShapeUtil } from './ArrowShapeUtil'\nimport {\n\tElbowArrowAxes,\n\tElbowArrowSide,\n\tElbowArrowSideAxes,\n\tElbowArrowSideDeltas,\n} from './elbow/definitions'\n\nexport interface UpdateArrowTargetStateOpts {\n\teditor: Editor\n\tpointInPageSpace: VecLike\n\tarrow: TLArrowShape | undefined\n\tisPrecise: boolean\n\tcurrentBinding: TLArrowBinding | undefined\n\t/** The binding from the opposite end of the arrow, if one exists. */\n\toppositeBinding: TLArrowBinding | undefined\n}\n\nexport interface ArrowTargetState {\n\ttarget: TLShape\n\tarrowKind: TLArrowShapeKind\n\n\thandlesInPageSpace: {\n\t\ttop: { point: VecLike; isEnabled: boolean }\n\t\tbottom: { point: VecLike; isEnabled: boolean }\n\t\tleft: { point: VecLike; isEnabled: boolean }\n\t\tright: { point: VecLike; isEnabled: boolean }\n\t}\n\n\tisExact: boolean\n\tisPrecise: boolean\n\n\tcenterInPageSpace: VecLike\n\tanchorInPageSpace: VecLike\n\tsnap: ElbowArrowSnap\n\tnormalizedAnchor: VecLike\n}\n\nconst arrowTargetStore = new WeakCache<Editor, Atom<ArrowTargetState | null>>()\n\nfunction getArrowTargetAtom(editor: Editor) {\n\treturn arrowTargetStore.get(editor, () => atom('arrowTarget', null))\n}\n\nexport function getArrowTargetState(editor: Editor) {\n\treturn getArrowTargetAtom(editor).get()\n}\n\nexport function clearArrowTargetState(editor: Editor) {\n\tgetArrowTargetAtom(editor).set(null)\n}\n\nexport function updateArrowTargetState({\n\teditor,\n\tpointInPageSpace,\n\tarrow,\n\tisPrecise,\n\tcurrentBinding,\n\toppositeBinding,\n}: UpdateArrowTargetStateOpts): ArrowTargetState | null {\n\tconst util = editor.getShapeUtil<ArrowShapeUtil>('arrow')\n\n\t// no target picking when ctrl is held:\n\tif (util.options.shouldIgnoreTargets(editor)) {\n\t\tgetArrowTargetAtom(editor).set(null)\n\t\treturn null\n\t}\n\n\tconst isExact = util.options.shouldBeExact(editor)\n\n\tconst arrowKind = arrow ? arrow.props.kind : editor.getStyleForNextShape(ArrowShapeKindStyle)\n\n\tconst target = editor.getShapeAtPoint(pointInPageSpace, {\n\t\thitInside: true,\n\t\thitFrameInside: true,\n\t\tmargin: arrowKind === 'elbow' ? 8 : 0,\n\t\tfilter: (targetShape) => {\n\t\t\treturn (\n\t\t\t\t!targetShape.isLocked &&\n\t\t\t\teditor.canBindShapes({\n\t\t\t\t\tfromShape: arrow ?? targetFilterFallback,\n\t\t\t\t\ttoShape: targetShape,\n\t\t\t\t\tbinding: 'arrow',\n\t\t\t\t})\n\t\t\t)\n\t\t},\n\t})\n\n\tif (!target) {\n\t\tgetArrowTargetAtom(editor).set(null)\n\t\treturn null\n\t}\n\n\tconst targetGeometryInTargetSpace = editor.getShapeGeometry(target)\n\tconst targetBoundsInTargetSpace = Box.ZeroFix(targetGeometryInTargetSpace.bounds)\n\tconst targetCenterInTargetSpace = targetGeometryInTargetSpace.center\n\tconst targetTransform = editor.getShapePageTransform(target)\n\tconst pointInTargetSpace = editor.getPointInShapeSpace(target, pointInPageSpace)\n\n\tconst castDistance = Math.max(\n\t\ttargetGeometryInTargetSpace.bounds.width,\n\t\ttargetGeometryInTargetSpace.bounds.height\n\t)\n\n\tconst handlesInPageSpace = mapObjectMapValues(ElbowArrowSideDeltas, (side, delta) => {\n\t\tconst axis = ElbowArrowAxes[ElbowArrowSideAxes[side]]\n\n\t\tconst farPoint = Vec.Mul(delta, castDistance).add(targetCenterInTargetSpace)\n\n\t\tlet isEnabled = false\n\t\tlet handlePointInTargetSpace: VecLike = axis.v(\n\t\t\ttargetBoundsInTargetSpace[side],\n\t\t\ttargetBoundsInTargetSpace[axis.crossMid]\n\t\t)\n\t\tlet furthestDistance = 0\n\n\t\tconst intersections = targetGeometryInTargetSpace.intersectLineSegment(\n\t\t\ttargetCenterInTargetSpace,\n\t\t\tfarPoint,\n\t\t\tGeometry2dFilters.EXCLUDE_NON_STANDARD\n\t\t)\n\t\tfor (const intersection of intersections) {\n\t\t\tconst distance = Vec.Dist2(intersection, targetCenterInTargetSpace)\n\t\t\tif (distance > furthestDistance) {\n\t\t\t\tfurthestDistance = distance\n\t\t\t\thandlePointInTargetSpace = intersection\n\t\t\t\tisEnabled = targetGeometryInTargetSpace.isClosed\n\t\t\t}\n\t\t}\n\n\t\tconst handlePointInPageSpace = targetTransform.applyToPoint(handlePointInTargetSpace)\n\n\t\treturn { point: handlePointInPageSpace, isEnabled, far: targetTransform.applyToPoint(farPoint) }\n\t})\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst minDistScaled = util.options.minElbowHandleDistance / zoomLevel\n\n\tconst targetCenterInPageSpace = targetTransform.applyToPoint(targetCenterInTargetSpace)\n\tfor (const side of objectMapKeys(handlesInPageSpace)) {\n\t\tconst handle = handlesInPageSpace[side]\n\t\tif (Vec.DistMin(handle.point, targetCenterInPageSpace, minDistScaled)) {\n\t\t\thandle.isEnabled = false\n\t\t}\n\t}\n\n\tlet precise = isPrecise || isExact\n\n\tif (!precise) {\n\t\t// If we're switching to a new bound shape, then precise only if moving slowly\n\t\tif (!currentBinding || (currentBinding && target.id !== currentBinding.toId)) {\n\t\t\tprecise = editor.inputs.pointerVelocity.len() < 0.5\n\t\t}\n\t}\n\n\tif (!isPrecise) {\n\t\tif (!targetGeometryInTargetSpace.isClosed) {\n\t\t\tprecise = true\n\t\t}\n\n\t\t// Double check that we're not going to be doing an imprecise snap on\n\t\t// the same shape twice, as this would result in a zero length line\n\t\tif (oppositeBinding && target.id === oppositeBinding.toId && oppositeBinding.props.isPrecise) {\n\t\t\tprecise = true\n\t\t}\n\t}\n\n\tconst shouldSnapCenter = !isExact && precise && targetGeometryInTargetSpace.isClosed\n\tconst shouldSnapEdges =\n\t\t!isExact && ((precise && arrowKind === 'elbow') || !targetGeometryInTargetSpace.isClosed)\n\tconst shouldSnapEdgePoints =\n\t\t!isExact && precise && arrowKind === 'elbow' && targetGeometryInTargetSpace.isClosed\n\tconst shouldSnapNone = precise && (targetGeometryInTargetSpace.isClosed || isExact)\n\tconst shouldSnapCenterAxis =\n\t\t!isExact && precise && arrowKind === 'elbow' && targetGeometryInTargetSpace.isClosed\n\n\t// we run through all the snapping options from least to most specific:\n\tlet snap: ElbowArrowSnap = 'none'\n\tlet anchorInPageSpace: VecLike = pointInPageSpace\n\n\tif (!shouldSnapNone) {\n\t\tsnap = 'center'\n\t\tanchorInPageSpace = targetCenterInPageSpace\n\t}\n\n\tif (shouldSnapEdges) {\n\t\tconst snapDistance = shouldSnapNone\n\t\t\t? calculateSnapDistance(\n\t\t\t\t\teditor,\n\t\t\t\t\ttargetBoundsInTargetSpace,\n\t\t\t\t\tutil.options.elbowArrowEdgeSnapDistance\n\t\t\t\t)\n\t\t\t: Infinity\n\n\t\tconst nearestPointOnEdgeInTargetSpace = targetGeometryInTargetSpace.nearestPoint(\n\t\t\tpointInTargetSpace,\n\t\t\t{\n\t\t\t\tincludeLabels: false,\n\t\t\t\tincludeInternal: false,\n\t\t\t}\n\t\t)\n\n\t\tconst nearestPointOnEdgeInPageSpace = targetTransform.applyToPoint(\n\t\t\tnearestPointOnEdgeInTargetSpace\n\t\t)\n\n\t\tconst distance = Vec.Dist(nearestPointOnEdgeInPageSpace, pointInPageSpace)\n\n\t\tif (distance < snapDistance) {\n\t\t\tsnap = 'edge'\n\t\t\tanchorInPageSpace = nearestPointOnEdgeInPageSpace\n\t\t}\n\t}\n\n\tif (shouldSnapCenterAxis) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tutil.options.elbowArrowAxisSnapDistance\n\t\t)\n\n\t\tconst distanceFromXAxis = Vec.DistanceToLineSegment(\n\t\t\thandlesInPageSpace.left.far,\n\t\t\thandlesInPageSpace.right.far,\n\t\t\tpointInPageSpace\n\t\t)\n\t\tconst distanceFromYAxis = Vec.DistanceToLineSegment(\n\t\t\thandlesInPageSpace.top.far,\n\t\t\thandlesInPageSpace.bottom.far,\n\t\t\tpointInPageSpace\n\t\t)\n\n\t\tconst snapAxis =\n\t\t\tdistanceFromXAxis < distanceFromYAxis && distanceFromXAxis < snapDistance\n\t\t\t\t? 'x'\n\t\t\t\t: distanceFromYAxis < snapDistance\n\t\t\t\t\t? 'y'\n\t\t\t\t\t: null\n\n\t\tif (snapAxis) {\n\t\t\tconst axis = ElbowArrowAxes[snapAxis]\n\n\t\t\tconst loDist2 = Vec.Dist2(handlesInPageSpace[axis.loEdge].far, pointInPageSpace)\n\t\t\tconst hiDist2 = Vec.Dist2(handlesInPageSpace[axis.hiEdge].far, pointInPageSpace)\n\n\t\t\tconst side = loDist2 < hiDist2 ? axis.loEdge : axis.hiEdge\n\n\t\t\tif (handlesInPageSpace[side].isEnabled) {\n\t\t\t\tsnap = 'edge-point'\n\t\t\t\tanchorInPageSpace = handlesInPageSpace[side].point\n\t\t\t}\n\t\t}\n\t}\n\n\tif (shouldSnapEdgePoints) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tutil.options.elbowArrowPointSnapDistance\n\t\t)\n\n\t\tlet closestSide: ElbowArrowSide | null = null\n\t\tlet closestDistance = Infinity\n\n\t\tfor (const [side, handle] of objectMapEntries(handlesInPageSpace)) {\n\t\t\tif (!handle.isEnabled) continue\n\t\t\tconst distance = Vec.Dist(handle.point, pointInPageSpace)\n\t\t\tif (distance < snapDistance && distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSide = side\n\t\t\t}\n\t\t}\n\n\t\tif (closestSide) {\n\t\t\tsnap = 'edge-point'\n\t\t\tanchorInPageSpace = handlesInPageSpace[closestSide].point\n\t\t}\n\t}\n\n\tif (shouldSnapCenter) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tarrowKind === 'elbow'\n\t\t\t\t? util.options.elbowArrowCenterSnapDistance\n\t\t\t\t: util.options.arcArrowCenterSnapDistance\n\t\t)\n\n\t\tif (Vec.Dist(pointInTargetSpace, targetBoundsInTargetSpace.center) < snapDistance) {\n\t\t\tsnap = 'center'\n\t\t\tanchorInPageSpace = targetCenterInPageSpace\n\t\t}\n\t}\n\n\tconst snapPointInTargetSpace = editor.getPointInShapeSpace(target, anchorInPageSpace)\n\n\tconst normalizedAnchor = {\n\t\tx: invLerp(\n\t\t\ttargetBoundsInTargetSpace.minX,\n\t\t\ttargetBoundsInTargetSpace.maxX,\n\t\t\tsnapPointInTargetSpace.x\n\t\t),\n\t\ty: invLerp(\n\t\t\ttargetBoundsInTargetSpace.minY,\n\t\t\ttargetBoundsInTargetSpace.maxY,\n\t\t\tsnapPointInTargetSpace.y\n\t\t),\n\t}\n\n\tconst result: ArrowTargetState = {\n\t\ttarget,\n\t\tarrowKind,\n\t\thandlesInPageSpace,\n\t\tcenterInPageSpace: targetCenterInPageSpace,\n\t\tanchorInPageSpace,\n\t\tisExact,\n\t\tisPrecise: precise,\n\t\tsnap,\n\t\tnormalizedAnchor,\n\t}\n\n\tgetArrowTargetAtom(editor).set(result)\n\n\treturn result\n}\n\nconst targetFilterFallback = { type: 'arrow' }\n\n/**\n * Funky math but we want the snap distance to be 4 at the minimum and either 16 or 15% of the\n * smaller dimension of the target shape, whichever is smaller\n */\nfunction calculateSnapDistance(\n\teditor: Editor,\n\ttargetBoundsInTargetSpace: Box,\n\tidealSnapDistance: number\n) {\n\treturn (\n\t\tclamp(\n\t\t\tMath.min(targetBoundsInTargetSpace.width, targetBoundsInTargetSpace.height) * 0.15,\n\t\t\t4,\n\t\t\tidealSnapDistance\n\t\t) / editor.getZoomLevel()\n\t)\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EACC;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAKA;AAAA,EAEA;AAAA,OACM;AAEP;AAAA,EACC;AAAA,EAEA;AAAA,EACA;AAAA,OACM;AAgCP,MAAM,mBAAmB,IAAI,UAAiD;AAE9E,SAAS,mBAAmB,QAAgB;AAC3C,SAAO,iBAAiB,IAAI,QAAQ,MAAM,KAAK,eAAe,IAAI,CAAC;AACpE;AAEO,SAAS,oBAAoB,QAAgB;AACnD,SAAO,mBAAmB,MAAM,EAAE,IAAI;AACvC;AAEO,SAAS,sBAAsB,QAAgB;AACrD,qBAAmB,MAAM,EAAE,IAAI,IAAI;AACpC;AAEO,SAAS,uBAAuB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAwD;AACvD,QAAM,OAAO,OAAO,aAA6B,OAAO;AAGxD,MAAI,KAAK,QAAQ,oBAAoB,MAAM,GAAG;AAC7C,uBAAmB,MAAM,EAAE,IAAI,IAAI;AACnC,WAAO;AAAA,EACR;AAEA,QAAM,UAAU,KAAK,QAAQ,cAAc,MAAM;AAEjD,QAAM,YAAY,QAAQ,MAAM,MAAM,OAAO,OAAO,qBAAqB,mBAAmB;AAE5F,QAAM,SAAS,OAAO,gBAAgB,kBAAkB;AAAA,IACvD,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,QAAQ,cAAc,UAAU,IAAI;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n\tArrowShapeKindStyle,\n\tatom,\n\tAtom,\n\tBox,\n\tclamp,\n\tEditor,\n\tElbowArrowSnap,\n\tGeometry2dFilters,\n\tinvLerp,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n\tobjectMapKeys,\n\tTLArrowBinding,\n\tTLArrowShape,\n\tTLArrowShapeKind,\n\tTLShape,\n\tVec,\n\tVecLike,\n\tWeakCache,\n} from '@tldraw/editor'\nimport { ArrowShapeUtil } from './ArrowShapeUtil'\nimport {\n\tElbowArrowAxes,\n\tElbowArrowSide,\n\tElbowArrowSideAxes,\n\tElbowArrowSideDeltas,\n} from './elbow/definitions'\n\nexport interface UpdateArrowTargetStateOpts {\n\teditor: Editor\n\tpointInPageSpace: VecLike\n\tarrow: TLArrowShape | undefined\n\tisPrecise: boolean\n\tcurrentBinding: TLArrowBinding | undefined\n\t/** The binding from the opposite end of the arrow, if one exists. */\n\toppositeBinding: TLArrowBinding | undefined\n}\n\nexport interface ArrowTargetState {\n\ttarget: TLShape\n\tarrowKind: TLArrowShapeKind\n\n\thandlesInPageSpace: {\n\t\ttop: { point: VecLike; isEnabled: boolean }\n\t\tbottom: { point: VecLike; isEnabled: boolean }\n\t\tleft: { point: VecLike; isEnabled: boolean }\n\t\tright: { point: VecLike; isEnabled: boolean }\n\t}\n\n\tisExact: boolean\n\tisPrecise: boolean\n\n\tcenterInPageSpace: VecLike\n\tanchorInPageSpace: VecLike\n\tsnap: ElbowArrowSnap\n\tnormalizedAnchor: VecLike\n}\n\nconst arrowTargetStore = new WeakCache<Editor, Atom<ArrowTargetState | null>>()\n\nfunction getArrowTargetAtom(editor: Editor) {\n\treturn arrowTargetStore.get(editor, () => atom('arrowTarget', null))\n}\n\nexport function getArrowTargetState(editor: Editor) {\n\treturn getArrowTargetAtom(editor).get()\n}\n\nexport function clearArrowTargetState(editor: Editor) {\n\tgetArrowTargetAtom(editor).set(null)\n}\n\nexport function updateArrowTargetState({\n\teditor,\n\tpointInPageSpace,\n\tarrow,\n\tisPrecise,\n\tcurrentBinding,\n\toppositeBinding,\n}: UpdateArrowTargetStateOpts): ArrowTargetState | null {\n\tconst util = editor.getShapeUtil<ArrowShapeUtil>('arrow')\n\n\t// no target picking when ctrl is held:\n\tif (util.options.shouldIgnoreTargets(editor)) {\n\t\tgetArrowTargetAtom(editor).set(null)\n\t\treturn null\n\t}\n\n\tconst isExact = util.options.shouldBeExact(editor)\n\n\tconst arrowKind = arrow ? arrow.props.kind : editor.getStyleForNextShape(ArrowShapeKindStyle)\n\n\tconst target = editor.getShapeAtPoint(pointInPageSpace, {\n\t\thitInside: true,\n\t\thitFrameInside: true,\n\t\tmargin: arrowKind === 'elbow' ? 8 : [8, 0],\n\t\tfilter: (targetShape) => {\n\t\t\treturn (\n\t\t\t\t!targetShape.isLocked &&\n\t\t\t\teditor.canBindShapes({\n\t\t\t\t\tfromShape: arrow ?? targetFilterFallback,\n\t\t\t\t\ttoShape: targetShape,\n\t\t\t\t\tbinding: 'arrow',\n\t\t\t\t})\n\t\t\t)\n\t\t},\n\t})\n\n\tif (!target) {\n\t\tgetArrowTargetAtom(editor).set(null)\n\t\treturn null\n\t}\n\n\tconst targetGeometryInTargetSpace = editor.getShapeGeometry(target)\n\tconst targetBoundsInTargetSpace = Box.ZeroFix(targetGeometryInTargetSpace.bounds)\n\tconst targetCenterInTargetSpace = targetGeometryInTargetSpace.center\n\tconst targetTransform = editor.getShapePageTransform(target)\n\tconst pointInTargetSpace = editor.getPointInShapeSpace(target, pointInPageSpace)\n\n\tconst castDistance = Math.max(\n\t\ttargetGeometryInTargetSpace.bounds.width,\n\t\ttargetGeometryInTargetSpace.bounds.height\n\t)\n\n\tconst handlesInPageSpace = mapObjectMapValues(ElbowArrowSideDeltas, (side, delta) => {\n\t\tconst axis = ElbowArrowAxes[ElbowArrowSideAxes[side]]\n\n\t\tconst farPoint = Vec.Mul(delta, castDistance).add(targetCenterInTargetSpace)\n\n\t\tlet isEnabled = false\n\t\tlet handlePointInTargetSpace: VecLike = axis.v(\n\t\t\ttargetBoundsInTargetSpace[side],\n\t\t\ttargetBoundsInTargetSpace[axis.crossMid]\n\t\t)\n\t\tlet furthestDistance = 0\n\n\t\tconst intersections = targetGeometryInTargetSpace.intersectLineSegment(\n\t\t\ttargetCenterInTargetSpace,\n\t\t\tfarPoint,\n\t\t\tGeometry2dFilters.EXCLUDE_NON_STANDARD\n\t\t)\n\t\tfor (const intersection of intersections) {\n\t\t\tconst distance = Vec.Dist2(intersection, targetCenterInTargetSpace)\n\t\t\tif (distance > furthestDistance) {\n\t\t\t\tfurthestDistance = distance\n\t\t\t\thandlePointInTargetSpace = intersection\n\t\t\t\tisEnabled = targetGeometryInTargetSpace.isClosed\n\t\t\t}\n\t\t}\n\n\t\tconst handlePointInPageSpace = targetTransform.applyToPoint(handlePointInTargetSpace)\n\n\t\treturn { point: handlePointInPageSpace, isEnabled, far: targetTransform.applyToPoint(farPoint) }\n\t})\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst minDistScaled = util.options.minElbowHandleDistance / zoomLevel\n\n\tconst targetCenterInPageSpace = targetTransform.applyToPoint(targetCenterInTargetSpace)\n\tfor (const side of objectMapKeys(handlesInPageSpace)) {\n\t\tconst handle = handlesInPageSpace[side]\n\t\tif (Vec.DistMin(handle.point, targetCenterInPageSpace, minDistScaled)) {\n\t\t\thandle.isEnabled = false\n\t\t}\n\t}\n\n\tlet precise = isPrecise || isExact\n\n\tif (!precise) {\n\t\t// If we're switching to a new bound shape, then precise only if moving slowly\n\t\tif (!currentBinding || (currentBinding && target.id !== currentBinding.toId)) {\n\t\t\tprecise = editor.inputs.pointerVelocity.len() < 0.5\n\t\t}\n\t}\n\n\tif (!isPrecise) {\n\t\tif (!targetGeometryInTargetSpace.isClosed) {\n\t\t\tprecise = true\n\t\t}\n\n\t\t// Double check that we're not going to be doing an imprecise snap on\n\t\t// the same shape twice, as this would result in a zero length line\n\t\tif (oppositeBinding && target.id === oppositeBinding.toId && oppositeBinding.props.isPrecise) {\n\t\t\tprecise = true\n\t\t}\n\t}\n\n\tconst shouldSnapCenter = !isExact && precise && targetGeometryInTargetSpace.isClosed\n\t// const shouldSnapEdges = !isExact && (precise || !targetGeometryInTargetSpace.isClosed)\n\tconst shouldSnapEdges =\n\t\t!isExact && ((precise && arrowKind === 'elbow') || !targetGeometryInTargetSpace.isClosed)\n\tconst shouldSnapEdgePoints =\n\t\t!isExact && precise && arrowKind === 'elbow' && targetGeometryInTargetSpace.isClosed\n\tconst shouldSnapNone = precise && (targetGeometryInTargetSpace.isClosed || isExact)\n\tconst shouldSnapCenterAxis =\n\t\t!isExact && precise && arrowKind === 'elbow' && targetGeometryInTargetSpace.isClosed\n\n\t// we run through all the snapping options from least to most specific:\n\tlet snap: ElbowArrowSnap = 'none'\n\tlet anchorInPageSpace: VecLike = pointInPageSpace\n\n\tif (!shouldSnapNone) {\n\t\tsnap = 'center'\n\t\tanchorInPageSpace = targetCenterInPageSpace\n\t}\n\n\tif (shouldSnapEdges) {\n\t\tconst snapDistance = shouldSnapNone\n\t\t\t? calculateSnapDistance(\n\t\t\t\t\teditor,\n\t\t\t\t\ttargetBoundsInTargetSpace,\n\t\t\t\t\tutil.options.elbowArrowEdgeSnapDistance\n\t\t\t\t)\n\t\t\t: Infinity\n\n\t\tconst nearestPointOnEdgeInTargetSpace = targetGeometryInTargetSpace.nearestPoint(\n\t\t\tpointInTargetSpace,\n\t\t\t{\n\t\t\t\tincludeLabels: false,\n\t\t\t\tincludeInternal: false,\n\t\t\t}\n\t\t)\n\n\t\tconst nearestPointOnEdgeInPageSpace = targetTransform.applyToPoint(\n\t\t\tnearestPointOnEdgeInTargetSpace\n\t\t)\n\n\t\tconst distance = Vec.Dist(nearestPointOnEdgeInPageSpace, pointInPageSpace)\n\n\t\tif (distance < snapDistance) {\n\t\t\tsnap = 'edge'\n\t\t\tanchorInPageSpace = nearestPointOnEdgeInPageSpace\n\t\t}\n\t}\n\n\tif (shouldSnapCenterAxis) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tutil.options.elbowArrowAxisSnapDistance\n\t\t)\n\n\t\tconst distanceFromXAxis = Vec.DistanceToLineSegment(\n\t\t\thandlesInPageSpace.left.far,\n\t\t\thandlesInPageSpace.right.far,\n\t\t\tpointInPageSpace\n\t\t)\n\t\tconst distanceFromYAxis = Vec.DistanceToLineSegment(\n\t\t\thandlesInPageSpace.top.far,\n\t\t\thandlesInPageSpace.bottom.far,\n\t\t\tpointInPageSpace\n\t\t)\n\n\t\tconst snapAxis =\n\t\t\tdistanceFromXAxis < distanceFromYAxis && distanceFromXAxis < snapDistance\n\t\t\t\t? 'x'\n\t\t\t\t: distanceFromYAxis < snapDistance\n\t\t\t\t\t? 'y'\n\t\t\t\t\t: null\n\n\t\tif (snapAxis) {\n\t\t\tconst axis = ElbowArrowAxes[snapAxis]\n\n\t\t\tconst loDist2 = Vec.Dist2(handlesInPageSpace[axis.loEdge].far, pointInPageSpace)\n\t\t\tconst hiDist2 = Vec.Dist2(handlesInPageSpace[axis.hiEdge].far, pointInPageSpace)\n\n\t\t\tconst side = loDist2 < hiDist2 ? axis.loEdge : axis.hiEdge\n\n\t\t\tif (handlesInPageSpace[side].isEnabled) {\n\t\t\t\tsnap = 'edge-point'\n\t\t\t\tanchorInPageSpace = handlesInPageSpace[side].point\n\t\t\t}\n\t\t}\n\t}\n\n\tif (shouldSnapEdgePoints) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tutil.options.elbowArrowPointSnapDistance\n\t\t)\n\n\t\tlet closestSide: ElbowArrowSide | null = null\n\t\tlet closestDistance = Infinity\n\n\t\tfor (const [side, handle] of objectMapEntries(handlesInPageSpace)) {\n\t\t\tif (!handle.isEnabled) continue\n\t\t\tconst distance = Vec.Dist(handle.point, pointInPageSpace)\n\t\t\tif (distance < snapDistance && distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSide = side\n\t\t\t}\n\t\t}\n\n\t\tif (closestSide) {\n\t\t\tsnap = 'edge-point'\n\t\t\tanchorInPageSpace = handlesInPageSpace[closestSide].point\n\t\t}\n\t}\n\n\tif (shouldSnapCenter) {\n\t\tconst snapDistance = calculateSnapDistance(\n\t\t\teditor,\n\t\t\ttargetBoundsInTargetSpace,\n\t\t\tarrowKind === 'elbow'\n\t\t\t\t? util.options.elbowArrowCenterSnapDistance\n\t\t\t\t: util.options.arcArrowCenterSnapDistance\n\t\t)\n\n\t\tif (Vec.Dist(pointInTargetSpace, targetBoundsInTargetSpace.center) < snapDistance) {\n\t\t\tsnap = 'center'\n\t\t\tanchorInPageSpace = targetCenterInPageSpace\n\t\t}\n\t}\n\n\tconst snapPointInTargetSpace = editor.getPointInShapeSpace(target, anchorInPageSpace)\n\n\tconst normalizedAnchor = {\n\t\tx: invLerp(\n\t\t\ttargetBoundsInTargetSpace.minX,\n\t\t\ttargetBoundsInTargetSpace.maxX,\n\t\t\tsnapPointInTargetSpace.x\n\t\t),\n\t\ty: invLerp(\n\t\t\ttargetBoundsInTargetSpace.minY,\n\t\t\ttargetBoundsInTargetSpace.maxY,\n\t\t\tsnapPointInTargetSpace.y\n\t\t),\n\t}\n\n\tconst result: ArrowTargetState = {\n\t\ttarget,\n\t\tarrowKind,\n\t\thandlesInPageSpace,\n\t\tcenterInPageSpace: targetCenterInPageSpace,\n\t\tanchorInPageSpace,\n\t\tisExact,\n\t\tisPrecise: precise,\n\t\tsnap,\n\t\tnormalizedAnchor,\n\t}\n\n\tgetArrowTargetAtom(editor).set(result)\n\n\treturn result\n}\n\nconst targetFilterFallback = { type: 'arrow' }\n\n/**\n * Funky math but we want the snap distance to be 4 at the minimum and either 16 or 15% of the\n * smaller dimension of the target shape, whichever is smaller\n */\nfunction calculateSnapDistance(\n\teditor: Editor,\n\ttargetBoundsInTargetSpace: Box,\n\tidealSnapDistance: number\n) {\n\treturn (\n\t\tclamp(\n\t\t\tMath.min(targetBoundsInTargetSpace.width, targetBoundsInTargetSpace.height) * 0.15,\n\t\t\t4,\n\t\t\tidealSnapDistance\n\t\t) / editor.getZoomLevel()\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -96,7 +96,7 @@ function ElbowArrowDebug({ arrow }) {
|
|
|
96
96
|
y: fullBox.minY - 3,
|
|
97
97
|
fontSize: 10,
|
|
98
98
|
fill: "black",
|
|
99
|
-
stroke: "var(--color-background)",
|
|
99
|
+
stroke: "var(--tl-color-background)",
|
|
100
100
|
strokeWidth: 2,
|
|
101
101
|
paintOrder: "stroke",
|
|
102
102
|
children: label
|
|
@@ -109,7 +109,7 @@ function ElbowArrowDebug({ arrow }) {
|
|
|
109
109
|
y: info.A.expanded.y,
|
|
110
110
|
fontSize: 10,
|
|
111
111
|
fill: "black",
|
|
112
|
-
stroke: "var(--color-background)",
|
|
112
|
+
stroke: "var(--tl-color-background)",
|
|
113
113
|
strokeWidth: 2,
|
|
114
114
|
paintOrder: "stroke",
|
|
115
115
|
children: [
|
|
@@ -126,7 +126,7 @@ function ElbowArrowDebug({ arrow }) {
|
|
|
126
126
|
y: info.B.expanded.y,
|
|
127
127
|
fontSize: 10,
|
|
128
128
|
fill: "black",
|
|
129
|
-
stroke: "var(--color-background)",
|
|
129
|
+
stroke: "var(--tl-color-background)",
|
|
130
130
|
strokeWidth: 2,
|
|
131
131
|
paintOrder: "stroke",
|
|
132
132
|
children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, TLArrowShape, useEditor, useValue, VecLike } from '@tldraw/editor'\nimport { SVGProps } from 'react'\nimport { getArrowBindings } from '../shared'\nimport { ElbowArrowEdge } from './definitions'\nimport { getElbowArrowInfo } from './getElbowArrowInfo'\n\nexport function ElbowArrowDebug({ arrow }: { arrow: TLArrowShape }) {\n\tconst editor = useEditor()\n\tconst info = useValue(\n\t\t'elbow arrow grid',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tconst info = getElbowArrowInfo(\n\t\t\t\t\teditor,\n\t\t\t\t\teditor.getShape(arrow.id)!,\n\t\t\t\t\tgetArrowBindings(editor, arrow)\n\t\t\t\t)\n\t\t\t\treturn info\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err)\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t\t[editor, arrow.id]\n\t)\n\n\tif (!info) return null\n\n\tconst fullBox = Box.Common([info.A.original, info.B.original]).expandBy(50)\n\n\tconst label = info.route?.name ?? ''\n\n\tconst midPoint = info.route?.midpointHandle\n\n\treturn (\n\t\t<>\n\t\t\t{info.midX !== null && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: info.midX, y: fullBox.minY }}\n\t\t\t\t\tb={{ x: info.midX, y: fullBox.maxY }}\n\t\t\t\t\tstroke=\"red\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{info.midY !== null && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: fullBox.minX, y: info.midY }}\n\t\t\t\t\tb={{ x: fullBox.maxX, y: info.midY }}\n\t\t\t\t\tstroke=\"blue\"\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{midPoint?.axis === 'x' && info.midXRange && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: info.midXRange.lo, y: midPoint.point.y }}\n\t\t\t\t\tb={{ x: info.midXRange.hi, y: midPoint.point.y }}\n\t\t\t\t\tstroke=\"red\"\n\t\t\t\t\tstrokeDasharray={'0 2'}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{midPoint?.axis === 'y' && info.midYRange && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: midPoint.point.x, y: info.midYRange.lo }}\n\t\t\t\t\tb={{ x: midPoint.point.x, y: info.midYRange.hi }}\n\t\t\t\t\tstroke=\"blue\"\n\t\t\t\t\tstrokeDasharray={'0 2'}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t<DebugBox box={info.A.original} stroke=\"orange\" />\n\t\t\t<DebugBox box={info.A.expanded} stroke=\"orange\" strokeWidth={0.5} />\n\t\t\t<DebugBox\n\t\t\t\tbox={info.A.original.clone().expandBy(info.options.minElbowLegLength)}\n\t\t\t\tstroke=\"orange\"\n\t\t\t\tstrokeWidth={0.5}\n\t\t\t/>\n\t\t\t<DebugBox box={info.B.original} stroke=\"lightskyblue\" />\n\t\t\t<DebugBox box={info.B.expanded} stroke=\"lightskyblue\" strokeWidth={0.5} />\n\t\t\t<DebugBox\n\t\t\t\tbox={info.B.original.clone().expandBy(info.options.minElbowLegLength)}\n\t\t\t\tstroke=\"lightskyblue\"\n\t\t\t\tstrokeWidth={0.5}\n\t\t\t/>\n\n\t\t\t<DebugEdge edge={info.A.edges.top} axis=\"x\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.top} axis=\"x\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.right} axis=\"y\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.right} axis=\"y\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.bottom} axis=\"x\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.bottom} axis=\"x\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.left} axis=\"y\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.left} axis=\"y\" stroke=\"lightskyblue\" />\n\n\t\t\t{info.route && <DebugRoute route={info.route.points} strokeWidth={10} />}\n\n\t\t\t<text\n\t\t\t\tx={fullBox.minX + 5}\n\t\t\t\ty={fullBox.minY - 3}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\t{label}\n\t\t\t</text>\n\t\t\t<text\n\t\t\t\tx={info.A.expanded.x}\n\t\t\t\ty={info.A.expanded.y}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\tA{info.route && `, ${info.route.aEdgePicking}`}\n\t\t\t\t{info.A.isPoint && `, point`}\n\t\t\t</text>\n\t\t\t<text\n\t\t\t\tx={info.B.expanded.x}\n\t\t\t\ty={info.B.expanded.y}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\tB{info.route && `, ${info.route.bEdgePicking}`}\n\t\t\t\t{info.B.isPoint && `, point`}\n\t\t\t</text>\n\t\t</>\n\t)\n}\n\nfunction DebugLine({ a, b, ...props }: { a: VecLike; b: VecLike } & SVGProps<SVGLineElement>) {\n\treturn (\n\t\t<line\n\t\t\tfill=\"none\"\n\t\t\tstrokeWidth={1}\n\t\t\tstrokeDasharray=\"4,4\"\n\t\t\tstroke=\"green\"\n\t\t\tx1={a.x}\n\t\t\ty1={a.y}\n\t\t\tx2={b.x}\n\t\t\ty2={b.y}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction DebugRoute({ route, ...props }: { route: VecLike[] } & SVGProps<SVGPolylineElement>) {\n\treturn (\n\t\t<polyline\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"darkorchid\"\n\t\t\tstrokeWidth={3}\n\t\t\topacity={0.5}\n\t\t\tpoints={route.map((r) => `${r.x},${r.y}`).join(' ')}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction DebugEdge({\n\tedge,\n\taxis,\n\t...props\n}: {\n\tedge: ElbowArrowEdge | null\n\taxis: 'x' | 'y'\n} & Omit<SVGProps<SVGLineElement>, 'scale'>) {\n\tif (!edge || edge.expanded === null) return null\n\tconst vec = (vec: VecLike) => (axis === 'x' ? { x: vec.y, y: vec.x } : vec)\n\n\treturn (\n\t\t<g>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded, y: edge.cross.min })}\n\t\t\t\tb={vec({ x: edge.expanded, y: edge.cross.max })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded - 4, y: edge.cross.min })}\n\t\t\t\tb={vec({ x: edge.expanded + 4, y: edge.cross.min })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded - 4, y: edge.cross.max })}\n\t\t\t\tb={vec({ x: edge.expanded + 4, y: edge.cross.max })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</g>\n\t)\n}\n\nfunction DebugBox({ box, ...props }: { box: Box } & SVGProps<SVGRectElement>) {\n\treturn (\n\t\t<rect\n\t\t\tx={box.minX}\n\t\t\ty={box.minY}\n\t\t\twidth={box.width}\n\t\t\theight={box.height}\n\t\t\tstrokeDasharray=\"4,4\"\n\t\t\tstrokeWidth={1}\n\t\t\tfill=\"none\"\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { Box, TLArrowShape, useEditor, useValue, VecLike } from '@tldraw/editor'\nimport { SVGProps } from 'react'\nimport { getArrowBindings } from '../shared'\nimport { ElbowArrowEdge } from './definitions'\nimport { getElbowArrowInfo } from './getElbowArrowInfo'\n\nexport function ElbowArrowDebug({ arrow }: { arrow: TLArrowShape }) {\n\tconst editor = useEditor()\n\tconst info = useValue(\n\t\t'elbow arrow grid',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tconst info = getElbowArrowInfo(\n\t\t\t\t\teditor,\n\t\t\t\t\teditor.getShape(arrow.id)!,\n\t\t\t\t\tgetArrowBindings(editor, arrow)\n\t\t\t\t)\n\t\t\t\treturn info\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err)\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t\t[editor, arrow.id]\n\t)\n\n\tif (!info) return null\n\n\tconst fullBox = Box.Common([info.A.original, info.B.original]).expandBy(50)\n\n\tconst label = info.route?.name ?? ''\n\n\tconst midPoint = info.route?.midpointHandle\n\n\treturn (\n\t\t<>\n\t\t\t{info.midX !== null && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: info.midX, y: fullBox.minY }}\n\t\t\t\t\tb={{ x: info.midX, y: fullBox.maxY }}\n\t\t\t\t\tstroke=\"red\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{info.midY !== null && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: fullBox.minX, y: info.midY }}\n\t\t\t\t\tb={{ x: fullBox.maxX, y: info.midY }}\n\t\t\t\t\tstroke=\"blue\"\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{midPoint?.axis === 'x' && info.midXRange && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: info.midXRange.lo, y: midPoint.point.y }}\n\t\t\t\t\tb={{ x: info.midXRange.hi, y: midPoint.point.y }}\n\t\t\t\t\tstroke=\"red\"\n\t\t\t\t\tstrokeDasharray={'0 2'}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{midPoint?.axis === 'y' && info.midYRange && (\n\t\t\t\t<DebugLine\n\t\t\t\t\ta={{ x: midPoint.point.x, y: info.midYRange.lo }}\n\t\t\t\t\tb={{ x: midPoint.point.x, y: info.midYRange.hi }}\n\t\t\t\t\tstroke=\"blue\"\n\t\t\t\t\tstrokeDasharray={'0 2'}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t<DebugBox box={info.A.original} stroke=\"orange\" />\n\t\t\t<DebugBox box={info.A.expanded} stroke=\"orange\" strokeWidth={0.5} />\n\t\t\t<DebugBox\n\t\t\t\tbox={info.A.original.clone().expandBy(info.options.minElbowLegLength)}\n\t\t\t\tstroke=\"orange\"\n\t\t\t\tstrokeWidth={0.5}\n\t\t\t/>\n\t\t\t<DebugBox box={info.B.original} stroke=\"lightskyblue\" />\n\t\t\t<DebugBox box={info.B.expanded} stroke=\"lightskyblue\" strokeWidth={0.5} />\n\t\t\t<DebugBox\n\t\t\t\tbox={info.B.original.clone().expandBy(info.options.minElbowLegLength)}\n\t\t\t\tstroke=\"lightskyblue\"\n\t\t\t\tstrokeWidth={0.5}\n\t\t\t/>\n\n\t\t\t<DebugEdge edge={info.A.edges.top} axis=\"x\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.top} axis=\"x\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.right} axis=\"y\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.right} axis=\"y\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.bottom} axis=\"x\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.bottom} axis=\"x\" stroke=\"lightskyblue\" />\n\t\t\t<DebugEdge edge={info.A.edges.left} axis=\"y\" stroke=\"orange\" />\n\t\t\t<DebugEdge edge={info.B.edges.left} axis=\"y\" stroke=\"lightskyblue\" />\n\n\t\t\t{info.route && <DebugRoute route={info.route.points} strokeWidth={10} />}\n\n\t\t\t<text\n\t\t\t\tx={fullBox.minX + 5}\n\t\t\t\ty={fullBox.minY - 3}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--tl-color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\t{label}\n\t\t\t</text>\n\t\t\t<text\n\t\t\t\tx={info.A.expanded.x}\n\t\t\t\ty={info.A.expanded.y}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--tl-color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\tA{info.route && `, ${info.route.aEdgePicking}`}\n\t\t\t\t{info.A.isPoint && `, point`}\n\t\t\t</text>\n\t\t\t<text\n\t\t\t\tx={info.B.expanded.x}\n\t\t\t\ty={info.B.expanded.y}\n\t\t\t\tfontSize={10}\n\t\t\t\tfill=\"black\"\n\t\t\t\tstroke=\"var(--tl-color-background)\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t\tpaintOrder=\"stroke\"\n\t\t\t>\n\t\t\t\tB{info.route && `, ${info.route.bEdgePicking}`}\n\t\t\t\t{info.B.isPoint && `, point`}\n\t\t\t</text>\n\t\t</>\n\t)\n}\n\nfunction DebugLine({ a, b, ...props }: { a: VecLike; b: VecLike } & SVGProps<SVGLineElement>) {\n\treturn (\n\t\t<line\n\t\t\tfill=\"none\"\n\t\t\tstrokeWidth={1}\n\t\t\tstrokeDasharray=\"4,4\"\n\t\t\tstroke=\"green\"\n\t\t\tx1={a.x}\n\t\t\ty1={a.y}\n\t\t\tx2={b.x}\n\t\t\ty2={b.y}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction DebugRoute({ route, ...props }: { route: VecLike[] } & SVGProps<SVGPolylineElement>) {\n\treturn (\n\t\t<polyline\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"darkorchid\"\n\t\t\tstrokeWidth={3}\n\t\t\topacity={0.5}\n\t\t\tpoints={route.map((r) => `${r.x},${r.y}`).join(' ')}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction DebugEdge({\n\tedge,\n\taxis,\n\t...props\n}: {\n\tedge: ElbowArrowEdge | null\n\taxis: 'x' | 'y'\n} & Omit<SVGProps<SVGLineElement>, 'scale'>) {\n\tif (!edge || edge.expanded === null) return null\n\tconst vec = (vec: VecLike) => (axis === 'x' ? { x: vec.y, y: vec.x } : vec)\n\n\treturn (\n\t\t<g>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded, y: edge.cross.min })}\n\t\t\t\tb={vec({ x: edge.expanded, y: edge.cross.max })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded - 4, y: edge.cross.min })}\n\t\t\t\tb={vec({ x: edge.expanded + 4, y: edge.cross.min })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t\t<DebugLine\n\t\t\t\ta={vec({ x: edge.expanded - 4, y: edge.cross.max })}\n\t\t\t\tb={vec({ x: edge.expanded + 4, y: edge.cross.max })}\n\t\t\t\tstrokeDasharray=\"0\"\n\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</g>\n\t)\n}\n\nfunction DebugBox({ box, ...props }: { box: Box } & SVGProps<SVGRectElement>) {\n\treturn (\n\t\t<rect\n\t\t\tx={box.minX}\n\t\t\ty={box.minY}\n\t\t\twidth={box.width}\n\t\t\theight={box.height}\n\t\t\tstrokeDasharray=\"4,4\"\n\t\t\tstrokeWidth={1}\n\t\t\tfill=\"none\"\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["info", "vec"]
|
|
7
7
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ShapeUtil,
|
|
9
9
|
drawShapeMigrations,
|
|
10
10
|
drawShapeProps,
|
|
11
|
+
getColorValue,
|
|
11
12
|
last,
|
|
12
13
|
lerp,
|
|
13
14
|
rng,
|
|
@@ -206,7 +207,7 @@ function DrawShapeSvg({ shape, zoomOverride }) {
|
|
|
206
207
|
{
|
|
207
208
|
d: svgInk(allPointsFromSegments, options),
|
|
208
209
|
strokeLinecap: "round",
|
|
209
|
-
fill: theme
|
|
210
|
+
fill: getColorValue(theme, shape.props.color, "solid")
|
|
210
211
|
}
|
|
211
212
|
)
|
|
212
213
|
] });
|
|
@@ -230,8 +231,8 @@ function DrawShapeSvg({ shape, zoomOverride }) {
|
|
|
230
231
|
{
|
|
231
232
|
d: solidStrokePath,
|
|
232
233
|
strokeLinecap: "round",
|
|
233
|
-
fill: isDot ? theme
|
|
234
|
-
stroke: theme
|
|
234
|
+
fill: isDot ? getColorValue(theme, shape.props.color, "solid") : "none",
|
|
235
|
+
stroke: getColorValue(theme, shape.props.color, "solid"),
|
|
235
236
|
strokeWidth: sw,
|
|
236
237
|
strokeDasharray: isDot ? "none" : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment),
|
|
237
238
|
strokeDashoffset: "0"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/draw/DrawShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLDrawShapeSegment,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\ttoFixed,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { getDrawShapeStrokeDashArray, getFreehandOptions, getPointsFromSegments } from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromSegments(shape.props.segments)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: toFixed(scaleX * x),\n\t\t\t\t\t\ty: toFixed(scaleY * y),\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverride?: number }) {\n\tconst theme = useDefaultColorTheme()\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 0 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed && shape.props.fill && allPointsFromSegments.length > 1 ? (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t)}\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<path\n\t\t\t\t\td={svgInk(allPointsFromSegments, options)}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={theme
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLDrawShapeSegment,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\ttoFixed,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { getDrawShapeStrokeDashArray, getFreehandOptions, getPointsFromSegments } from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromSegments(shape.props.segments)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: toFixed(scaleX * x),\n\t\t\t\t\t\ty: toFixed(scaleY * y),\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverride?: number }) {\n\tconst theme = useDefaultColorTheme()\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 0 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed && shape.props.fill && allPointsFromSegments.length > 1 ? (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t)}\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<path\n\t\t\t\t\td={svgInk(allPointsFromSegments, options)}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\t/>\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill\n\t\t\t\td={solidStrokePath}\n\t\t\t\ttheme={theme}\n\t\t\t\tcolor={shape.props.color}\n\t\t\t\tfill={isDot || shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\tscale={shape.props.scale}\n\t\t\t/>\n\t\t\t<path\n\t\t\t\td={solidStrokePath}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tfill={isDot ? getColorValue(theme, shape.props.color, 'solid') : 'none'}\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={sw}\n\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -108,7 +108,7 @@ class EmbedShapeUtil extends BaseBoxShapeUtil {
|
|
|
108
108
|
border: 0,
|
|
109
109
|
boxShadow: getRotatedBoxShadow(pageRotation),
|
|
110
110
|
borderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,
|
|
111
|
-
background: embedInfo?.definition.backgroundColor ?? "var(--color-background)",
|
|
111
|
+
background: embedInfo?.definition.backgroundColor ?? "var(--tl-color-background)",
|
|
112
112
|
width: w,
|
|
113
113
|
height: h
|
|
114
114
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/embed/EmbedShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
compact,
|
|
10
10
|
frameShapeMigrations,
|
|
11
11
|
frameShapeProps,
|
|
12
|
+
getColorValue,
|
|
12
13
|
getDefaultColorTheme,
|
|
13
14
|
lerp,
|
|
14
15
|
resizeBox,
|
|
@@ -67,6 +68,9 @@ class FrameShapeUtil extends BaseBoxShapeUtil {
|
|
|
67
68
|
canResizeChildren() {
|
|
68
69
|
return false;
|
|
69
70
|
}
|
|
71
|
+
isExportBoundsContainer() {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
70
74
|
getDefaultProps() {
|
|
71
75
|
return { w: 160 * 2, h: 90 * 2, name: "", color: "black" };
|
|
72
76
|
}
|
|
@@ -151,12 +155,12 @@ class FrameShapeUtil extends BaseBoxShapeUtil {
|
|
|
151
155
|
[shape.id]
|
|
152
156
|
);
|
|
153
157
|
const showFrameColors = this.options.showColors;
|
|
154
|
-
const
|
|
155
|
-
const frameFill =
|
|
156
|
-
const frameStroke =
|
|
157
|
-
const frameHeadingStroke = showFrameColors ?
|
|
158
|
-
const frameHeadingFill = showFrameColors ?
|
|
159
|
-
const frameHeadingText =
|
|
158
|
+
const colorToUse = showFrameColors ? shape.props.color : "black";
|
|
159
|
+
const frameFill = getColorValue(theme, colorToUse, "frameFill");
|
|
160
|
+
const frameStroke = getColorValue(theme, colorToUse, "frameStroke");
|
|
161
|
+
const frameHeadingStroke = showFrameColors ? getColorValue(theme, colorToUse, "frameHeadingStroke") : theme.background;
|
|
162
|
+
const frameHeadingFill = showFrameColors ? getColorValue(theme, colorToUse, "frameHeadingFill") : theme.background;
|
|
163
|
+
const frameHeadingText = getColorValue(theme, colorToUse, "frameText");
|
|
160
164
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
161
165
|
/* @__PURE__ */ jsx(SVGContainer, { children: /* @__PURE__ */ jsx(
|
|
162
166
|
"rect",
|
|
@@ -199,12 +203,12 @@ class FrameShapeUtil extends BaseBoxShapeUtil {
|
|
|
199
203
|
const spans = this.editor.textMeasure.measureTextSpans(frameTitle, opts);
|
|
200
204
|
const text = createTextJsxFromSpans(this.editor, spans, opts);
|
|
201
205
|
const showFrameColors = this.options.showColors;
|
|
202
|
-
const
|
|
203
|
-
const frameFill =
|
|
204
|
-
const frameStroke =
|
|
205
|
-
const frameHeadingStroke = showFrameColors ?
|
|
206
|
-
const frameHeadingFill = showFrameColors ?
|
|
207
|
-
const frameHeadingText =
|
|
206
|
+
const colorToUse = showFrameColors ? shape.props.color : "black";
|
|
207
|
+
const frameFill = getColorValue(theme, colorToUse, "frameFill");
|
|
208
|
+
const frameStroke = getColorValue(theme, colorToUse, "frameStroke");
|
|
209
|
+
const frameHeadingStroke = showFrameColors ? getColorValue(theme, colorToUse, "frameHeadingStroke") : theme.background;
|
|
210
|
+
const frameHeadingFill = showFrameColors ? getColorValue(theme, colorToUse, "frameHeadingFill") : theme.background;
|
|
211
|
+
const frameHeadingText = getColorValue(theme, colorToUse, "frameText");
|
|
208
212
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
209
213
|
/* @__PURE__ */ jsx(
|
|
210
214
|
"rect",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/frame/FrameShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tDefaultColorStyle,\n\tGeometry2d,\n\tGroup2d,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLClickEventInfo,\n\tTLDragShapesOutInfo,\n\tTLDragShapesOverInfo,\n\tTLFrameShape,\n\tTLFrameShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLShapeUtilConstructor,\n\tclamp,\n\tcompact,\n\tframeShapeMigrations,\n\tframeShapeProps,\n\tgetDefaultColorTheme,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { fitFrameToContent, getFrameChildrenBounds } from '../../utils/frames/frames'\nimport {\n\tTLCreateTextJsxFromSpansOpts,\n\tcreateTextJsxFromSpans,\n} from '../shared/createTextJsxFromSpans'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { FrameHeading } from './components/FrameHeading'\nimport {\n\tgetFrameHeadingOpts,\n\tgetFrameHeadingSide,\n\tgetFrameHeadingSize,\n\tgetFrameHeadingTranslation,\n} from './frameHelpers'\n\n// Some of these values are repeated in CSS and need to match\nconst FRAME_HEADING_EXTRA_WIDTH = 12\nconst FRAME_HEADING_MIN_WIDTH = 32\nconst FRAME_HEADING_NOCOLORS_OFFSET_X = -7\nconst FRAME_HEADING_OFFSET_Y = 4\n\n/** @public */\nexport interface FrameShapeOptions {\n\t/**\n\t * When true, the frame will display colors for the shape's headings and background.\n\t */\n\tshowColors: boolean\n}\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\n/** @public */\nexport class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {\n\tstatic override type = 'frame' as const\n\tstatic override props = frameShapeProps\n\tstatic override migrations = frameShapeMigrations\n\n\toverride options: FrameShapeOptions = {\n\t\tshowColors: false,\n\t}\n\n\t// evil crimes :)\n\t// By default, showColors is off. Because they use style props, which are picked up\n\t// automatically, we don't have DefaultColorStyle in the props in the schema by default.\n\t// Instead, when someone calls .configure to turn the option on, we manually add in the color\n\t// style here so it plays nicely with the other editor APIs.\n\tstatic override configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\tconst withOptions = super.configure.call(this, options) as T\n\t\tif ((options as any).showColors) {\n\t\t\t;(withOptions as any).props = { ...withOptions.props, color: DefaultColorStyle }\n\t\t}\n\t\treturn withOptions\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride canResize() {\n\t\treturn true\n\t}\n\n\toverride canResizeChildren() {\n\t\treturn false\n\t}\n\n\toverride getDefaultProps(): TLFrameShape['props'] {\n\t\treturn { w: 160 * 2, h: 90 * 2, name: '', color: 'black' }\n\t}\n\n\toverride getAriaDescriptor(shape: TLFrameShape) {\n\t\treturn shape.props.name\n\t}\n\n\toverride getGeometry(shape: TLFrameShape): Geometry2d {\n\t\tconst { editor } = this\n\n\t\tconst z = editor.getZoomLevel()\n\n\t\t// Which dimension measures the top edge after rotation?\n\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\n\t\t// Get the size of the heading (max width equal to the rotatedTopEdgeWidth)\n\t\tconst opts = getFrameHeadingOpts(rotatedTopEdgeWidth, false)\n\t\tconst headingSize = getFrameHeadingSize(editor, shape, opts)\n\n\t\t// If NOT showing frame colors, we need to offset the label\n\t\t// to the left so that the title is in line with the shape edge\n\t\t// and add that extra width to the right side of the label\n\t\tconst isShowingFrameColors = this.options.showColors\n\n\t\t// Scale everything into **screen space**\n\t\tconst extraWidth = FRAME_HEADING_EXTRA_WIDTH / z\n\t\tconst minWidth = FRAME_HEADING_MIN_WIDTH / z\n\t\tconst maxWidth = rotatedTopEdgeWidth + (isShowingFrameColors ? 1 : extraWidth)\n\n\t\tconst labelWidth = headingSize.w / z\n\t\tconst labelHeight = headingSize.h / z\n\n\t\tconst clampedLabelWidth = clamp(labelWidth + extraWidth, minWidth, maxWidth)\n\n\t\tconst offsetX = (isShowingFrameColors ? -1 : FRAME_HEADING_NOCOLORS_OFFSET_X) / z\n\t\tconst offsetY = FRAME_HEADING_OFFSET_Y / z\n\n\t\t// In page space\n\t\tconst width = isVertical ? labelHeight : clampedLabelWidth\n\t\tconst height = isVertical ? clampedLabelWidth : labelHeight\n\n\t\t// Calculate label position based on side. The position needs to always appear\n\t\t// at the top left of the shape, regardless of rotation. The label must be\n\t\t// between a minimum and maximum. The minimum is arbitrary; the maximum is the\n\t\t// width of the edge of the frame where the label will be shown.\n\n\t\tlet x: number, y: number\n\n\t\tswitch (labelSide) {\n\t\t\tcase 0: {\n\t\t\t\t// top\n\t\t\t\tx = offsetX\n\t\t\t\ty = -(labelHeight + offsetY)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 1: {\n\t\t\t\t// right\n\t\t\t\tx = -(labelHeight + offsetY)\n\t\t\t\ty = shape.props.h - (offsetX + clampedLabelWidth)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 2: {\n\t\t\t\t// bottom\n\t\t\t\tx = shape.props.w - (offsetX + clampedLabelWidth)\n\t\t\t\ty = shape.props.h + offsetY\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 3: {\n\t\t\t\t// left\n\t\t\t\tx = shape.props.w + offsetY\n\t\t\t\ty = offsetX\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: false,\n\t\t\t\t}),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getText(shape: TLFrameShape): string | undefined {\n\t\treturn shape.props.name\n\t}\n\n\toverride component(shape: TLFrameShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isCreating = useValue(\n\t\t\t'is creating this shape',\n\t\t\t() => {\n\t\t\t\tconst resizingState = this.editor.getStateDescendant('select.resizing')\n\t\t\t\tif (!resizingState) return false\n\t\t\t\tif (!resizingState.getIsActive()) return false\n\t\t\t\tconst info = (resizingState as typeof resizingState & { info: { isCreating: boolean } })\n\t\t\t\t\t?.info\n\t\t\t\tif (!info) return false\n\t\t\t\treturn info.isCreating && this.editor.getOnlySelectedShapeId() === shape.id\n\t\t\t},\n\t\t\t[shape.id]\n\t\t)\n\n\t\tconst showFrameColors = this.options.showColors\n\n\t\tconst color = theme[shape.props.color]\n\t\tconst frameFill = showFrameColors ? color.frame.fill : theme.black.frame.fill\n\t\tconst frameStroke = showFrameColors ? color.frame.stroke : theme.black.frame.stroke\n\t\tconst frameHeadingStroke = showFrameColors ? color.frame.headingStroke : theme.background\n\t\tconst frameHeadingFill = showFrameColors ? color.frame.headingFill : theme.background\n\t\tconst frameHeadingText = showFrameColors ? color.frame.text : theme.text\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tclassName={classNames('tl-frame__body', { 'tl-frame__creating': isCreating })}\n\t\t\t\t\t\tfill={frameFill}\n\t\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: `calc(${shape.props.w}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\theight: `calc(${shape.props.h}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\ttransform: `translate(calc(-0.5px / var(--tl-zoom)), calc(-0.5px / var(--tl-zoom)))`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</SVGContainer>\n\t\t\t\t{isCreating ? null : (\n\t\t\t\t\t<FrameHeading\n\t\t\t\t\t\tid={shape.id}\n\t\t\t\t\t\tname={shape.props.name}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\tcolor={frameHeadingText}\n\t\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\t\toffsetX={showFrameColors ? -1 : -7}\n\t\t\t\t\t\tshowColors={this.options.showColors}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLFrameShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\n\t\t// rotate right 45 deg\n\t\tconst labelSide = getFrameHeadingSide(this.editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\t\tconst labelTranslate = getFrameHeadingTranslation(shape, labelSide, true)\n\n\t\t// Truncate with ellipsis\n\t\tconst opts: TLCreateTextJsxFromSpansOpts = getFrameHeadingOpts(rotatedTopEdgeWidth - 12, true)\n\n\t\tconst frameTitle = defaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203)\n\t\tconst labelBounds = getFrameHeadingSize(this.editor, shape, opts)\n\t\tconst spans = this.editor.textMeasure.measureTextSpans(frameTitle, opts)\n\t\tconst text = createTextJsxFromSpans(this.editor, spans, opts)\n\n\t\tconst showFrameColors = this.options.showColors\n\n\t\tconst color = theme[shape.props.color]\n\t\tconst frameFill = showFrameColors ? color.frame.fill : theme.black.frame.fill\n\t\tconst frameStroke = showFrameColors ? color.frame.stroke : theme.black.frame.stroke\n\t\tconst frameHeadingStroke = showFrameColors ? color.frame.headingStroke : theme.background\n\t\tconst frameHeadingFill = showFrameColors ? color.frame.headingFill : theme.background\n\t\tconst frameHeadingText = showFrameColors ? color.frame.text : theme.text\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect\n\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\tfill={frameFill}\n\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\tx={0}\n\t\t\t\t\trx={0}\n\t\t\t\t\try={0}\n\t\t\t\t/>\n\t\t\t\t<g fill={frameHeadingText} transform={labelTranslate}>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={labelBounds.x - (showFrameColors ? 0 : 6)}\n\t\t\t\t\t\ty={labelBounds.y - 6}\n\t\t\t\t\t\twidth={Math.min(rotatedTopEdgeWidth, labelBounds.width + 12)}\n\t\t\t\t\t\theight={labelBounds.height}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\trx={4}\n\t\t\t\t\t\try={4}\n\t\t\t\t\t/>\n\t\t\t\t\t<g transform={`translate(${showFrameColors ? 8 : 0}, 4)`}>{text}</g>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLFrameShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\tclassName={`tl-frame-indicator`}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride providesBackgroundForChildren(): boolean {\n\t\treturn true\n\t}\n\n\toverride canReceiveNewChildrenOfType(shape: TLShape) {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\treturn resizeBox(shape, info)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLFrameShape,\n\t\tendShape: TLFrameShape,\n\t\tt: number\n\t): TLFrameShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n\n\toverride onDoubleClickEdge(shape: TLFrameShape, info: TLClickEventInfo) {\n\t\tif (info.target !== 'selection') return\n\t\tconst { handle } = info\n\n\t\t// If handle is missing, we can't determine which edge was clicked\n\t\tif (!handle) return\n\n\t\tconst isHorizontalEdge = handle === 'left' || handle === 'right'\n\t\tconst isVerticalEdge = handle === 'top' || handle === 'bottom'\n\n\t\tconst childIds = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tconst children = compact(childIds.map((id) => this.editor.getShape(id)))\n\t\tif (!children.length) return\n\n\t\tconst { dx, dy, w, h } = getFrameChildrenBounds(children, this.editor, { padding: 10 })\n\n\t\tthis.editor.run(() => {\n\t\t\tconst changes: TLShapePartial[] = childIds.map((childId) => {\n\t\t\t\tconst childShape = this.editor.getShape(childId)!\n\t\t\t\treturn {\n\t\t\t\t\tid: childShape.id,\n\t\t\t\t\ttype: childShape.type,\n\t\t\t\t\tx: isHorizontalEdge ? childShape.x + dx : childShape.x,\n\t\t\t\t\ty: isVerticalEdge ? childShape.y + dy : childShape.y,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.editor.updateShapes(changes)\n\t\t})\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\tw: isHorizontalEdge ? w : shape.props.w,\n\t\t\t\th: isVerticalEdge ? h : shape.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onDoubleClickCorner(shape: TLFrameShape) {\n\t\tfitFrameToContent(this.editor, shape.id, { padding: 10 })\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t}\n\t}\n\n\toverride onDragShapesIn(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\t{ initialParentIds, initialIndices }: TLDragShapesOverInfo\n\t) {\n\t\tconst { editor } = this\n\n\t\tif (draggingShapes.every((s) => s.parentId === shape.id)) return\n\n\t\t// Check to see whether any of the shapes can have their old index restored\n\t\tlet canRestoreOriginalIndices = false\n\t\tconst previousChildren = draggingShapes.filter((s) => shape.id === initialParentIds.get(s.id))\n\n\t\tif (previousChildren.length > 0) {\n\t\t\tconst currentChildren = compact(\n\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t)\n\t\t\tif (previousChildren.every((s) => !currentChildren.find((c) => c.index === s.index))) {\n\t\t\t\tcanRestoreOriginalIndices = true\n\t\t\t}\n\t\t}\n\n\t\t// I can't imagine this happening, but if any of the children are the ancestor of the frame, quit here\n\t\tif (draggingShapes.some((s) => editor.hasAncestor(shape, s.id))) return\n\n\t\t// Reparent the shapes to the new parent\n\t\teditor.reparentShapes(draggingShapes, shape.id)\n\n\t\t// If we can restore the original indices, then do so\n\t\tif (canRestoreOriginalIndices) {\n\t\t\tfor (const shape of previousChildren) {\n\t\t\t\teditor.updateShape({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tindex: initialIndices.get(shape.id),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDragShapesOut(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\tinfo: TLDragShapesOutInfo\n\t): void {\n\t\tconst { editor } = this\n\t\t// When a user drags shapes out of a frame, and if we're not dragging into a new shape, then reparent\n\t\t// the dragging shapes (that are current children of the frame) onto the current page instead\n\t\tif (!info.nextDraggingOverShapeId) {\n\t\t\teditor.reparentShapes(\n\t\t\t\tdraggingShapes.filter(\n\t\t\t\t\t(s) => s.parentId === shape.id && this.canReceiveNewChildrenOfType(s)\n\t\t\t\t),\n\t\t\t\teditor.getCurrentPageId()\n\t\t\t)\n\t\t}\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tDefaultColorStyle,\n\tGeometry2d,\n\tGroup2d,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLClickEventInfo,\n\tTLDragShapesOutInfo,\n\tTLDragShapesOverInfo,\n\tTLFrameShape,\n\tTLFrameShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLShapeUtilConstructor,\n\tclamp,\n\tcompact,\n\tframeShapeMigrations,\n\tframeShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { fitFrameToContent, getFrameChildrenBounds } from '../../utils/frames/frames'\nimport {\n\tTLCreateTextJsxFromSpansOpts,\n\tcreateTextJsxFromSpans,\n} from '../shared/createTextJsxFromSpans'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { FrameHeading } from './components/FrameHeading'\nimport {\n\tgetFrameHeadingOpts,\n\tgetFrameHeadingSide,\n\tgetFrameHeadingSize,\n\tgetFrameHeadingTranslation,\n} from './frameHelpers'\n\n// Some of these values are repeated in CSS and need to match\nconst FRAME_HEADING_EXTRA_WIDTH = 12\nconst FRAME_HEADING_MIN_WIDTH = 32\nconst FRAME_HEADING_NOCOLORS_OFFSET_X = -7\nconst FRAME_HEADING_OFFSET_Y = 4\n\n/** @public */\nexport interface FrameShapeOptions {\n\t/**\n\t * When true, the frame will display colors for the shape's headings and background.\n\t */\n\tshowColors: boolean\n}\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\n/** @public */\nexport class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {\n\tstatic override type = 'frame' as const\n\tstatic override props = frameShapeProps\n\tstatic override migrations = frameShapeMigrations\n\n\toverride options: FrameShapeOptions = {\n\t\tshowColors: false,\n\t}\n\n\t// evil crimes :)\n\t// By default, showColors is off. Because they use style props, which are picked up\n\t// automatically, we don't have DefaultColorStyle in the props in the schema by default.\n\t// Instead, when someone calls .configure to turn the option on, we manually add in the color\n\t// style here so it plays nicely with the other editor APIs.\n\tstatic override configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\tconst withOptions = super.configure.call(this, options) as T\n\t\tif ((options as any).showColors) {\n\t\t\t;(withOptions as any).props = { ...withOptions.props, color: DefaultColorStyle }\n\t\t}\n\t\treturn withOptions\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride canResize() {\n\t\treturn true\n\t}\n\n\toverride canResizeChildren() {\n\t\treturn false\n\t}\n\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLFrameShape['props'] {\n\t\treturn { w: 160 * 2, h: 90 * 2, name: '', color: 'black' }\n\t}\n\n\toverride getAriaDescriptor(shape: TLFrameShape) {\n\t\treturn shape.props.name\n\t}\n\n\toverride getGeometry(shape: TLFrameShape): Geometry2d {\n\t\tconst { editor } = this\n\n\t\tconst z = editor.getZoomLevel()\n\n\t\t// Which dimension measures the top edge after rotation?\n\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\n\t\t// Get the size of the heading (max width equal to the rotatedTopEdgeWidth)\n\t\tconst opts = getFrameHeadingOpts(rotatedTopEdgeWidth, false)\n\t\tconst headingSize = getFrameHeadingSize(editor, shape, opts)\n\n\t\t// If NOT showing frame colors, we need to offset the label\n\t\t// to the left so that the title is in line with the shape edge\n\t\t// and add that extra width to the right side of the label\n\t\tconst isShowingFrameColors = this.options.showColors\n\n\t\t// Scale everything into **screen space**\n\t\tconst extraWidth = FRAME_HEADING_EXTRA_WIDTH / z\n\t\tconst minWidth = FRAME_HEADING_MIN_WIDTH / z\n\t\tconst maxWidth = rotatedTopEdgeWidth + (isShowingFrameColors ? 1 : extraWidth)\n\n\t\tconst labelWidth = headingSize.w / z\n\t\tconst labelHeight = headingSize.h / z\n\n\t\tconst clampedLabelWidth = clamp(labelWidth + extraWidth, minWidth, maxWidth)\n\n\t\tconst offsetX = (isShowingFrameColors ? -1 : FRAME_HEADING_NOCOLORS_OFFSET_X) / z\n\t\tconst offsetY = FRAME_HEADING_OFFSET_Y / z\n\n\t\t// In page space\n\t\tconst width = isVertical ? labelHeight : clampedLabelWidth\n\t\tconst height = isVertical ? clampedLabelWidth : labelHeight\n\n\t\t// Calculate label position based on side. The position needs to always appear\n\t\t// at the top left of the shape, regardless of rotation. The label must be\n\t\t// between a minimum and maximum. The minimum is arbitrary; the maximum is the\n\t\t// width of the edge of the frame where the label will be shown.\n\n\t\tlet x: number, y: number\n\n\t\tswitch (labelSide) {\n\t\t\tcase 0: {\n\t\t\t\t// top\n\t\t\t\tx = offsetX\n\t\t\t\ty = -(labelHeight + offsetY)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 1: {\n\t\t\t\t// right\n\t\t\t\tx = -(labelHeight + offsetY)\n\t\t\t\ty = shape.props.h - (offsetX + clampedLabelWidth)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 2: {\n\t\t\t\t// bottom\n\t\t\t\tx = shape.props.w - (offsetX + clampedLabelWidth)\n\t\t\t\ty = shape.props.h + offsetY\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 3: {\n\t\t\t\t// left\n\t\t\t\tx = shape.props.w + offsetY\n\t\t\t\ty = offsetX\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: false,\n\t\t\t\t}),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getText(shape: TLFrameShape): string | undefined {\n\t\treturn shape.props.name\n\t}\n\n\toverride component(shape: TLFrameShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isCreating = useValue(\n\t\t\t'is creating this shape',\n\t\t\t() => {\n\t\t\t\tconst resizingState = this.editor.getStateDescendant('select.resizing')\n\t\t\t\tif (!resizingState) return false\n\t\t\t\tif (!resizingState.getIsActive()) return false\n\t\t\t\tconst info = (resizingState as typeof resizingState & { info: { isCreating: boolean } })\n\t\t\t\t\t?.info\n\t\t\t\tif (!info) return false\n\t\t\t\treturn info.isCreating && this.editor.getOnlySelectedShapeId() === shape.id\n\t\t\t},\n\t\t\t[shape.id]\n\t\t)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tclassName={classNames('tl-frame__body', { 'tl-frame__creating': isCreating })}\n\t\t\t\t\t\tfill={frameFill}\n\t\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: `calc(${shape.props.w}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\theight: `calc(${shape.props.h}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\ttransform: `translate(calc(-0.5px / var(--tl-zoom)), calc(-0.5px / var(--tl-zoom)))`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</SVGContainer>\n\t\t\t\t{isCreating ? null : (\n\t\t\t\t\t<FrameHeading\n\t\t\t\t\t\tid={shape.id}\n\t\t\t\t\t\tname={shape.props.name}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\tcolor={frameHeadingText}\n\t\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\t\toffsetX={showFrameColors ? -1 : -7}\n\t\t\t\t\t\tshowColors={this.options.showColors}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLFrameShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\n\t\t// rotate right 45 deg\n\t\tconst labelSide = getFrameHeadingSide(this.editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\t\tconst labelTranslate = getFrameHeadingTranslation(shape, labelSide, true)\n\n\t\t// Truncate with ellipsis\n\t\tconst opts: TLCreateTextJsxFromSpansOpts = getFrameHeadingOpts(rotatedTopEdgeWidth - 12, true)\n\n\t\tconst frameTitle = defaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203)\n\t\tconst labelBounds = getFrameHeadingSize(this.editor, shape, opts)\n\t\tconst spans = this.editor.textMeasure.measureTextSpans(frameTitle, opts)\n\t\tconst text = createTextJsxFromSpans(this.editor, spans, opts)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect\n\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\tfill={frameFill}\n\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\tx={0}\n\t\t\t\t\trx={0}\n\t\t\t\t\try={0}\n\t\t\t\t/>\n\t\t\t\t<g fill={frameHeadingText} transform={labelTranslate}>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={labelBounds.x - (showFrameColors ? 0 : 6)}\n\t\t\t\t\t\ty={labelBounds.y - 6}\n\t\t\t\t\t\twidth={Math.min(rotatedTopEdgeWidth, labelBounds.width + 12)}\n\t\t\t\t\t\theight={labelBounds.height}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\trx={4}\n\t\t\t\t\t\try={4}\n\t\t\t\t\t/>\n\t\t\t\t\t<g transform={`translate(${showFrameColors ? 8 : 0}, 4)`}>{text}</g>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLFrameShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\tclassName={`tl-frame-indicator`}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride providesBackgroundForChildren(): boolean {\n\t\treturn true\n\t}\n\n\toverride canReceiveNewChildrenOfType(shape: TLShape) {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\treturn resizeBox(shape, info)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLFrameShape,\n\t\tendShape: TLFrameShape,\n\t\tt: number\n\t): TLFrameShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n\n\toverride onDoubleClickEdge(shape: TLFrameShape, info: TLClickEventInfo) {\n\t\tif (info.target !== 'selection') return\n\t\tconst { handle } = info\n\n\t\t// If handle is missing, we can't determine which edge was clicked\n\t\tif (!handle) return\n\n\t\tconst isHorizontalEdge = handle === 'left' || handle === 'right'\n\t\tconst isVerticalEdge = handle === 'top' || handle === 'bottom'\n\n\t\tconst childIds = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tconst children = compact(childIds.map((id) => this.editor.getShape(id)))\n\t\tif (!children.length) return\n\n\t\tconst { dx, dy, w, h } = getFrameChildrenBounds(children, this.editor, { padding: 10 })\n\n\t\tthis.editor.run(() => {\n\t\t\tconst changes: TLShapePartial[] = childIds.map((childId) => {\n\t\t\t\tconst childShape = this.editor.getShape(childId)!\n\t\t\t\treturn {\n\t\t\t\t\tid: childShape.id,\n\t\t\t\t\ttype: childShape.type,\n\t\t\t\t\tx: isHorizontalEdge ? childShape.x + dx : childShape.x,\n\t\t\t\t\ty: isVerticalEdge ? childShape.y + dy : childShape.y,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.editor.updateShapes(changes)\n\t\t})\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\tw: isHorizontalEdge ? w : shape.props.w,\n\t\t\t\th: isVerticalEdge ? h : shape.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onDoubleClickCorner(shape: TLFrameShape) {\n\t\tfitFrameToContent(this.editor, shape.id, { padding: 10 })\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t}\n\t}\n\n\toverride onDragShapesIn(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\t{ initialParentIds, initialIndices }: TLDragShapesOverInfo\n\t) {\n\t\tconst { editor } = this\n\n\t\tif (draggingShapes.every((s) => s.parentId === shape.id)) return\n\n\t\t// Check to see whether any of the shapes can have their old index restored\n\t\tlet canRestoreOriginalIndices = false\n\t\tconst previousChildren = draggingShapes.filter((s) => shape.id === initialParentIds.get(s.id))\n\n\t\tif (previousChildren.length > 0) {\n\t\t\tconst currentChildren = compact(\n\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t)\n\t\t\tif (previousChildren.every((s) => !currentChildren.find((c) => c.index === s.index))) {\n\t\t\t\tcanRestoreOriginalIndices = true\n\t\t\t}\n\t\t}\n\n\t\t// I can't imagine this happening, but if any of the children are the ancestor of the frame, quit here\n\t\tif (draggingShapes.some((s) => editor.hasAncestor(shape, s.id))) return\n\n\t\t// Reparent the shapes to the new parent\n\t\teditor.reparentShapes(draggingShapes, shape.id)\n\n\t\t// If we can restore the original indices, then do so\n\t\tif (canRestoreOriginalIndices) {\n\t\t\tfor (const shape of previousChildren) {\n\t\t\t\teditor.updateShape({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tindex: initialIndices.get(shape.id),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDragShapesOut(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\tinfo: TLDragShapesOutInfo\n\t): void {\n\t\tconst { editor } = this\n\t\t// When a user drags shapes out of a frame, and if we're not dragging into a new shape, then reparent\n\t\t// the dragging shapes (that are current children of the frame) onto the current page instead\n\t\tif (!info.nextDraggingOverShapeId) {\n\t\t\teditor.reparentShapes(\n\t\t\t\tdraggingShapes.filter(\n\t\t\t\t\t(s) => s.parentId === shape.id && this.canReceiveNewChildrenOfType(s)\n\t\t\t\t),\n\t\t\t\teditor.getCurrentPageId()\n\t\t\t)\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["shape"]
|
|
7
7
|
}
|
|
@@ -48,7 +48,7 @@ const FrameHeading = memo(function FrameHeading2({
|
|
|
48
48
|
className: "tl-frame-heading",
|
|
49
49
|
style: {
|
|
50
50
|
overflow: isEditing ? "visible" : "hidden",
|
|
51
|
-
maxWidth: `calc(var(--tl-zoom) * ${side === 0 || side === 2 ? Math.ceil(width) : Math.ceil(height)}px + ${showColors ? "0px" : "var(--frame-offset-width)"})`,
|
|
51
|
+
maxWidth: `calc(var(--tl-zoom) * ${side === 0 || side === 2 ? Math.ceil(width) : Math.ceil(height)}px + ${showColors ? "0px" : "var(--tl-frame-offset-width)"})`,
|
|
52
52
|
bottom: "100%",
|
|
53
53
|
transform: `${translation} scale(var(--tl-scale)) translateX(${offsetX}px)`
|
|
54
54
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/frame/components/FrameHeading.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLFrameShape, TLShapeId, useEditor, useIsEditing, useValue } from '@tldraw/editor'\nimport { memo, useEffect, useRef } from 'react'\nimport { getFrameHeadingSide, getFrameHeadingTranslation } from '../frameHelpers'\nimport { FrameLabelInput } from './FrameLabelInput'\n\nexport const FrameHeading = memo(function FrameHeading({\n\tid,\n\tname,\n\twidth,\n\theight,\n\tfill,\n\tstroke,\n\tcolor,\n\toffsetX,\n\tshowColors,\n}: {\n\tid: TLShapeId\n\tname: string\n\twidth: number\n\theight: number\n\tfill: string\n\tstroke: string\n\tcolor: string\n\toffsetX: number\n\tshowColors: boolean\n}) {\n\tconst editor = useEditor()\n\tconst { side, translation } = useValue(\n\t\t'shape rotation',\n\t\t() => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) {\n\t\t\t\t// meh\n\t\t\t\treturn {\n\t\t\t\t\tside: 0,\n\t\t\t\t\ttranslation: 'translate(0, 0)',\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\t\treturn {\n\t\t\t\tside: labelSide,\n\t\t\t\ttranslation: getFrameHeadingTranslation(shape, labelSide, false),\n\t\t\t}\n\t\t},\n\t\t[editor, offsetX, id]\n\t)\n\n\tconst rInput = useRef<HTMLInputElement>(null)\n\tconst isEditing = useIsEditing(id)\n\n\tuseEffect(() => {\n\t\tconst el = rInput.current\n\t\tif (el && isEditing) {\n\t\t\t// On iOS, we must focus here\n\t\t\tel.focus()\n\t\t\tel.select()\n\t\t}\n\t}, [rInput, isEditing])\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"tl-frame-heading\"\n\t\t\tstyle={{\n\t\t\t\toverflow: isEditing ? 'visible' : 'hidden',\n\t\t\t\tmaxWidth: `calc(var(--tl-zoom) * ${\n\t\t\t\t\tside === 0 || side === 2 ? Math.ceil(width) : Math.ceil(height)\n\t\t\t\t}px + ${showColors ? '0px' : 'var(--frame-offset-width)'})`,\n\t\t\t\tbottom: '100%',\n\t\t\t\ttransform: `${translation} scale(var(--tl-scale)) translateX(${offsetX}px)`,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-frame-heading-hit-area\"\n\t\t\t\tstyle={{ color, backgroundColor: fill, boxShadow: `inset 0px 0px 0px 1px ${stroke}` }}\n\t\t\t>\n\t\t\t\t<FrameLabelInput ref={rInput} id={id} name={name} isEditing={isEditing} />\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n"],
|
|
5
|
-
"mappings": "AA2EI;AA3EJ,SAAkC,WAAW,cAAc,gBAAgB;AAC3E,SAAS,MAAM,WAAW,cAAc;AACxC,SAAS,qBAAqB,kCAAkC;AAChE,SAAS,uBAAuB;AAEzB,MAAM,eAAe,KAAK,SAASA,cAAa;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAUG;AACF,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,MAAM,YAAY,IAAI;AAAA,IAC7B;AAAA,IACA,MAAM;AACL,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,OAAO;AAEX,eAAO;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACd;AAAA,MACD;AACA,YAAM,YAAY,oBAAoB,QAAQ,KAAK;AACnD,aAAO;AAAA,QACN,MAAM;AAAA,QACN,aAAa,2BAA2B,OAAO,WAAW,KAAK;AAAA,MAChE;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,SAAS,EAAE;AAAA,EACrB;AAEA,QAAM,SAAS,OAAyB,IAAI;AAC5C,QAAM,YAAY,aAAa,EAAE;AAEjC,YAAU,MAAM;AACf,UAAM,KAAK,OAAO;AAClB,QAAI,MAAM,WAAW;AAEpB,SAAG,MAAM;AACT,SAAG,OAAO;AAAA,IACX;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,OAAO;AAAA,QACN,UAAU,YAAY,YAAY;AAAA,QAClC,UAAU,yBACT,SAAS,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAC/D,QAAQ,aAAa,QAAQ,
|
|
4
|
+
"sourcesContent": ["import { TLFrameShape, TLShapeId, useEditor, useIsEditing, useValue } from '@tldraw/editor'\nimport { memo, useEffect, useRef } from 'react'\nimport { getFrameHeadingSide, getFrameHeadingTranslation } from '../frameHelpers'\nimport { FrameLabelInput } from './FrameLabelInput'\n\nexport const FrameHeading = memo(function FrameHeading({\n\tid,\n\tname,\n\twidth,\n\theight,\n\tfill,\n\tstroke,\n\tcolor,\n\toffsetX,\n\tshowColors,\n}: {\n\tid: TLShapeId\n\tname: string\n\twidth: number\n\theight: number\n\tfill: string\n\tstroke: string\n\tcolor: string\n\toffsetX: number\n\tshowColors: boolean\n}) {\n\tconst editor = useEditor()\n\tconst { side, translation } = useValue(\n\t\t'shape rotation',\n\t\t() => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) {\n\t\t\t\t// meh\n\t\t\t\treturn {\n\t\t\t\t\tside: 0,\n\t\t\t\t\ttranslation: 'translate(0, 0)',\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\t\treturn {\n\t\t\t\tside: labelSide,\n\t\t\t\ttranslation: getFrameHeadingTranslation(shape, labelSide, false),\n\t\t\t}\n\t\t},\n\t\t[editor, offsetX, id]\n\t)\n\n\tconst rInput = useRef<HTMLInputElement>(null)\n\tconst isEditing = useIsEditing(id)\n\n\tuseEffect(() => {\n\t\tconst el = rInput.current\n\t\tif (el && isEditing) {\n\t\t\t// On iOS, we must focus here\n\t\t\tel.focus()\n\t\t\tel.select()\n\t\t}\n\t}, [rInput, isEditing])\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"tl-frame-heading\"\n\t\t\tstyle={{\n\t\t\t\toverflow: isEditing ? 'visible' : 'hidden',\n\t\t\t\tmaxWidth: `calc(var(--tl-zoom) * ${\n\t\t\t\t\tside === 0 || side === 2 ? Math.ceil(width) : Math.ceil(height)\n\t\t\t\t}px + ${showColors ? '0px' : 'var(--tl-frame-offset-width)'})`,\n\t\t\t\tbottom: '100%',\n\t\t\t\ttransform: `${translation} scale(var(--tl-scale)) translateX(${offsetX}px)`,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-frame-heading-hit-area\"\n\t\t\t\tstyle={{ color, backgroundColor: fill, boxShadow: `inset 0px 0px 0px 1px ${stroke}` }}\n\t\t\t>\n\t\t\t\t<FrameLabelInput ref={rInput} id={id} name={name} isEditing={isEditing} />\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n"],
|
|
5
|
+
"mappings": "AA2EI;AA3EJ,SAAkC,WAAW,cAAc,gBAAgB;AAC3E,SAAS,MAAM,WAAW,cAAc;AACxC,SAAS,qBAAqB,kCAAkC;AAChE,SAAS,uBAAuB;AAEzB,MAAM,eAAe,KAAK,SAASA,cAAa;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAUG;AACF,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,MAAM,YAAY,IAAI;AAAA,IAC7B;AAAA,IACA,MAAM;AACL,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,OAAO;AAEX,eAAO;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACd;AAAA,MACD;AACA,YAAM,YAAY,oBAAoB,QAAQ,KAAK;AACnD,aAAO;AAAA,QACN,MAAM;AAAA,QACN,aAAa,2BAA2B,OAAO,WAAW,KAAK;AAAA,MAChE;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,SAAS,EAAE;AAAA,EACrB;AAEA,QAAM,SAAS,OAAyB,IAAI;AAC5C,QAAM,YAAY,aAAa,EAAE;AAEjC,YAAU,MAAM;AACf,UAAM,KAAK,OAAO;AAClB,QAAI,MAAM,WAAW;AAEpB,SAAG,MAAM;AACT,SAAG,OAAO;AAAA,IACX;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,OAAO;AAAA,QACN,UAAU,YAAY,YAAY;AAAA,QAClC,UAAU,yBACT,SAAS,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAC/D,QAAQ,aAAa,QAAQ,8BAA8B;AAAA,QAC3D,QAAQ;AAAA,QACR,WAAW,GAAG,WAAW,sCAAsC,OAAO;AAAA,MACvE;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO,EAAE,OAAO,iBAAiB,MAAM,WAAW,yBAAyB,MAAM,GAAG;AAAA,UAEpF,8BAAC,mBAAgB,KAAK,QAAQ,IAAQ,MAAY,WAAsB;AAAA;AAAA,MACzE;AAAA;AAAA,EACD;AAEF,CAAC;",
|
|
6
6
|
"names": ["FrameHeading"]
|
|
7
7
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
exhaustiveSwitchError,
|
|
12
12
|
geoShapeMigrations,
|
|
13
13
|
geoShapeProps,
|
|
14
|
+
getColorValue,
|
|
14
15
|
getDefaultColorTheme,
|
|
15
16
|
getFontsFromRichText,
|
|
16
17
|
isEqual,
|
|
@@ -181,7 +182,7 @@ class GeoShapeUtil extends BaseBoxShapeUtil {
|
|
|
181
182
|
verticalAlign,
|
|
182
183
|
richText,
|
|
183
184
|
isSelected: isOnlySelected,
|
|
184
|
-
labelColor: theme
|
|
185
|
+
labelColor: getColorValue(theme, props.labelColor, "solid"),
|
|
185
186
|
wrap: true
|
|
186
187
|
}
|
|
187
188
|
)
|
|
@@ -234,7 +235,7 @@ class GeoShapeUtil extends BaseBoxShapeUtil {
|
|
|
234
235
|
align: props.align,
|
|
235
236
|
verticalAlign: props.verticalAlign,
|
|
236
237
|
richText: props.richText,
|
|
237
|
-
labelColor: theme
|
|
238
|
+
labelColor: getColorValue(theme, props.labelColor, "solid"),
|
|
238
239
|
bounds,
|
|
239
240
|
padding: LABEL_PADDING
|
|
240
241
|
}
|