@tldraw/editor 4.6.0-next.fe1474dc57d8 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +412 -179
- package/dist-cjs/index.js +12 -23
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +3 -0
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js +180 -0
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js.map +7 -0
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +44 -249
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +3 -3
- package/dist-cjs/lib/editor/Editor.js +78 -28
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +98 -0
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +14 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +2 -2
- package/dist-cjs/lib/editor/overlays/OverlayManager.js +154 -0
- package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/OverlayUtil.js +92 -0
- package/dist-cjs/lib/editor/overlays/OverlayUtil.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +161 -0
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js +39 -0
- package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +3 -0
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +25 -23
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +32 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
- package/dist-cjs/lib/exports/fetchCache.js +1 -1
- package/dist-cjs/lib/exports/fetchCache.js.map +2 -2
- package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +3 -3
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +0 -28
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePeerIds.js +1 -36
- package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
- package/dist-cjs/lib/hooks/useShapeCulling.js +2 -1
- package/dist-cjs/lib/hooks/useShapeCulling.js.map +2 -2
- package/dist-cjs/lib/options.js +0 -1
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +20 -7
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -0
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +4 -4
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +412 -179
- package/dist-esm/index.mjs +19 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +3 -0
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs +160 -0
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs.map +7 -0
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +45 -250
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +3 -3
- package/dist-esm/lib/editor/Editor.mjs +78 -29
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +83 -0
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +14 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +2 -2
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs +136 -0
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/OverlayUtil.mjs +72 -0
- package/dist-esm/lib/editor/overlays/OverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +141 -0
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs +19 -0
- package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +3 -0
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +25 -23
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +32 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
- package/dist-esm/lib/exports/fetchCache.mjs +2 -2
- package/dist-esm/lib/exports/fetchCache.mjs.map +2 -2
- package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +3 -3
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -28
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePeerIds.mjs +2 -40
- package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useShapeCulling.mjs +2 -1
- package/dist-esm/lib/hooks/useShapeCulling.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +0 -1
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +20 -7
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -0
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +4 -4
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +4 -239
- package/package.json +7 -7
- package/src/index.ts +17 -39
- package/src/lib/TldrawEditor.tsx +9 -0
- package/src/lib/components/default-components/CanvasOverlays.tsx +208 -0
- package/src/lib/components/default-components/DefaultCanvas.tsx +49 -324
- package/src/lib/editor/Editor.test.ts +3 -1
- package/src/lib/editor/Editor.ts +80 -24
- package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +98 -0
- package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +14 -0
- package/src/lib/editor/overlays/OverlayManager.ts +183 -0
- package/src/lib/editor/overlays/OverlayUtil.ts +143 -0
- package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +216 -0
- package/src/lib/editor/overlays/getOverlayDisplayValues.ts +51 -0
- package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +9 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +34 -26
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +40 -3
- package/src/lib/editor/types/event-types.ts +2 -0
- package/src/lib/exports/fetchCache.ts +2 -4
- package/src/lib/exports/getSvgJsx.test.ts +3 -1
- package/src/lib/hooks/EditorComponentsContext.tsx +0 -27
- package/src/lib/hooks/useCanvasEvents.ts +13 -8
- package/src/lib/hooks/useEditorComponents.tsx +0 -28
- package/src/lib/hooks/usePeerIds.ts +6 -55
- package/src/lib/hooks/useShapeCulling.tsx +3 -1
- package/src/lib/options.ts +0 -7
- package/src/lib/utils/reparenting.ts +22 -9
- package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -0
- package/src/version.ts +4 -4
- package/dist-cjs/lib/components/GeometryDebuggingView.js +0 -115
- package/dist-cjs/lib/components/GeometryDebuggingView.js.map +0 -7
- package/dist-cjs/lib/components/LiveCollaborators.js +0 -152
- package/dist-cjs/lib/components/LiveCollaborators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +0 -234
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultBrush.js +0 -38
- package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +0 -71
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultCursor.js +0 -59
- package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultHandle.js +0 -56
- package/dist-cjs/lib/components/default-components/DefaultHandle.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultHandles.js +0 -28
- package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +0 -51
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js +0 -69
- package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +0 -107
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js +0 -28
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +0 -102
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +0 -170
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +0 -7
- package/dist-cjs/lib/hooks/useHandleEvents.js +0 -100
- package/dist-cjs/lib/hooks/useHandleEvents.js.map +0 -7
- package/dist-cjs/lib/hooks/useSelectionEvents.js +0 -98
- package/dist-cjs/lib/hooks/useSelectionEvents.js.map +0 -7
- package/dist-esm/lib/components/GeometryDebuggingView.mjs +0 -95
- package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +0 -7
- package/dist-esm/lib/components/LiveCollaborators.mjs +0 -135
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +0 -214
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs +0 -18
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +0 -41
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs +0 -29
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultHandle.mjs +0 -26
- package/dist-esm/lib/components/default-components/DefaultHandle.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs +0 -8
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +0 -21
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs +0 -39
- package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +0 -77
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs +0 -8
- package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +0 -82
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +0 -142
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +0 -7
- package/dist-esm/lib/hooks/useHandleEvents.mjs +0 -70
- package/dist-esm/lib/hooks/useHandleEvents.mjs.map +0 -7
- package/dist-esm/lib/hooks/useSelectionEvents.mjs +0 -78
- package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +0 -7
- package/src/lib/components/GeometryDebuggingView.tsx +0 -108
- package/src/lib/components/LiveCollaborators.tsx +0 -180
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +0 -300
- package/src/lib/components/default-components/DefaultBrush.tsx +0 -35
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +0 -52
- package/src/lib/components/default-components/DefaultCursor.tsx +0 -59
- package/src/lib/components/default-components/DefaultHandle.tsx +0 -42
- package/src/lib/components/default-components/DefaultHandles.tsx +0 -15
- package/src/lib/components/default-components/DefaultScribble.tsx +0 -31
- package/src/lib/components/default-components/DefaultSelectionForeground.tsx +0 -50
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +0 -104
- package/src/lib/components/default-components/DefaultShapeIndicatorErrorFallback.tsx +0 -9
- package/src/lib/components/default-components/DefaultShapeIndicators.tsx +0 -118
- package/src/lib/components/default-components/DefaultSnapIndictor.tsx +0 -174
- package/src/lib/hooks/useHandleEvents.ts +0 -88
- package/src/lib/hooks/useSelectionEvents.ts +0 -97
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/editor/types/event-types.ts"],
|
|
4
|
-
"sourcesContent": ["import { TLHandle, TLShape, VecModel } from '@tldraw/tlschema'\nimport { VecLike } from '../../primitives/Vec'\nimport { TLSelectionHandle } from './selection-types'\n\n/** @public */\nexport type UiEventType = 'pointer' | 'click' | 'keyboard' | 'wheel' | 'pinch' | 'zoom'\n\n/** @public */\nexport type TLPointerEventTarget =\n\t| { target: 'canvas'; shape?: undefined }\n\t| { target: 'selection'; handle?: TLSelectionHandle; shape?: undefined }\n\t| { target: 'shape'; shape: TLShape }\n\t| { target: 'handle'; shape: TLShape; handle: TLHandle }\n\n/** @public */\nexport type TLPointerEventName =\n\t| 'pointer_down'\n\t| 'pointer_move'\n\t| 'long_press'\n\t| 'pointer_up'\n\t| 'right_click'\n\t| 'middle_click'\n\n/** @public */\nexport type TLCLickEventName = 'double_click' | 'triple_click' | 'quadruple_click'\n\n/** @public */\nexport type TLPinchEventName = 'pinch_start' | 'pinch' | 'pinch_end'\n\n/** @public */\nexport type TLKeyboardEventName = 'key_down' | 'key_up' | 'key_repeat'\n\n/** @public */\nexport type TLEventName =\n\t| TLPointerEventName\n\t| TLCLickEventName\n\t| TLPinchEventName\n\t| TLKeyboardEventName\n\t| 'wheel'\n\t| 'cancel'\n\t| 'complete'\n\t| 'interrupt'\n\t| 'tick'\n\n/** @public */\nexport interface TLBaseEventInfo {\n\ttype: UiEventType\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n\taccelKey: boolean\n}\n\n/** @public */\nexport type TLPointerEventInfo = TLBaseEventInfo & {\n\ttype: 'pointer'\n\tname: TLPointerEventName\n\t// The pointer position in client space, i.e. clientX / clientY\n\tpoint: VecLike\n\tpointerId: number\n\tbutton: number\n\tisPen: boolean\n} & TLPointerEventTarget\n\n/** @public */\nexport type TLClickEventInfo = TLBaseEventInfo & {\n\ttype: 'click'\n\tname: TLCLickEventName\n\tpoint: VecLike\n\tpointerId: number\n\tbutton: number\n\tphase: 'down' | 'up' | 'settle'\n} & TLPointerEventTarget\n\n/** @public */\nexport type TLKeyboardEventInfo = TLBaseEventInfo & {\n\ttype: 'keyboard'\n\tname: TLKeyboardEventName\n\tkey: string\n\tcode: string\n}\n\n/** @public */\nexport type TLPinchEventInfo = TLBaseEventInfo & {\n\ttype: 'pinch'\n\tname: TLPinchEventName\n\tpoint: VecModel\n\tdelta: VecModel\n}\n\n/** @public */\nexport type TLWheelEventInfo = TLBaseEventInfo & {\n\ttype: 'wheel'\n\tname: 'wheel'\n\tdelta: VecModel\n\tpoint: VecModel\n}\n\n/** @public */\nexport interface TLCancelEventInfo {\n\ttype: 'misc'\n\tname: 'cancel'\n}\n/** @public */\nexport interface TLCompleteEventInfo {\n\ttype: 'misc'\n\tname: 'complete'\n}\n/** @public */\nexport interface TLInterruptEventInfo {\n\ttype: 'misc'\n\tname: 'interrupt'\n}\n/** @public */\nexport interface TLTickEventInfo {\n\ttype: 'misc'\n\tname: 'tick'\n\telapsed: number\n}\n\n/** @public */\nexport type TLEventInfo =\n\t| TLPointerEventInfo\n\t| TLClickEventInfo\n\t| TLKeyboardEventInfo\n\t| TLPinchEventInfo\n\t| TLWheelEventInfo\n\t| TLCancelEventInfo\n\t| TLCompleteEventInfo\n\t| TLInterruptEventInfo\n\t| TLTickEventInfo\n\n/** @public */\nexport type TLPointerEvent = (info: TLPointerEventInfo) => void\n/** @public */\nexport type TLClickEvent = (info: TLClickEventInfo) => void\n/** @public */\nexport type TLKeyboardEvent = (info: TLKeyboardEventInfo) => void\n/** @public */\nexport type TLPinchEvent = (info: TLPinchEventInfo) => void\n/** @public */\nexport type TLWheelEvent = (info: TLWheelEventInfo) => void\n/** @public */\nexport type TLCancelEvent = (info: TLCancelEventInfo) => void\n/** @public */\nexport type TLCompleteEvent = (info: TLCompleteEventInfo) => void\n/** @public */\nexport type TLInterruptEvent = (info: TLInterruptEventInfo) => void\n/** @public */\nexport type TLTickEvent = (info: TLTickEventInfo) => void\n\n/** @public */\nexport type UiEvent =\n\t| TLPointerEvent\n\t| TLClickEvent\n\t| TLKeyboardEvent\n\t| TLPinchEvent\n\t| TLCancelEvent\n\t| TLCompleteEvent\n\n/** @public */\nexport type TLEnterEventHandler = (info: any, from: string) => void\n/** @public */\nexport type TLExitEventHandler = (info: any, to: string) => void\n\n/** @public */\nexport interface TLEventHandlers {\n\tonPointerDown: TLPointerEvent\n\tonPointerMove: TLPointerEvent\n\tonLongPress: TLPointerEvent\n\tonRightClick: TLPointerEvent\n\tonDoubleClick: TLClickEvent\n\tonTripleClick: TLClickEvent\n\tonQuadrupleClick: TLClickEvent\n\tonMiddleClick: TLPointerEvent\n\tonPointerUp: TLPointerEvent\n\tonKeyDown: TLKeyboardEvent\n\tonKeyUp: TLKeyboardEvent\n\tonKeyRepeat: TLKeyboardEvent\n\tonWheel: TLWheelEvent\n\tonCancel: TLCancelEvent\n\tonComplete: TLCompleteEvent\n\tonInterrupt: TLInterruptEvent\n\tonTick: TLTickEvent\n}\n\n/** @public */\nexport const EVENT_NAME_MAP: Record<\n\tExclude<TLEventName, TLPinchEventName>,\n\tkeyof TLEventHandlers\n> = {\n\twheel: 'onWheel',\n\tpointer_down: 'onPointerDown',\n\tpointer_move: 'onPointerMove',\n\tlong_press: 'onLongPress',\n\tpointer_up: 'onPointerUp',\n\tright_click: 'onRightClick',\n\tmiddle_click: 'onMiddleClick',\n\tkey_down: 'onKeyDown',\n\tkey_up: 'onKeyUp',\n\tkey_repeat: 'onKeyRepeat',\n\tcancel: 'onCancel',\n\tcomplete: 'onComplete',\n\tinterrupt: 'onInterrupt',\n\tdouble_click: 'onDoubleClick',\n\ttriple_click: 'onTripleClick',\n\tquadruple_click: 'onQuadrupleClick',\n\ttick: 'onTick',\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { TLHandle, TLShape, VecModel } from '@tldraw/tlschema'\nimport { VecLike } from '../../primitives/Vec'\nimport { TLOverlay } from '../overlays/OverlayUtil'\nimport { TLSelectionHandle } from './selection-types'\n\n/** @public */\nexport type UiEventType = 'pointer' | 'click' | 'keyboard' | 'wheel' | 'pinch' | 'zoom'\n\n/** @public */\nexport type TLPointerEventTarget =\n\t| { target: 'canvas'; shape?: undefined }\n\t| { target: 'selection'; handle?: TLSelectionHandle; shape?: undefined }\n\t| { target: 'shape'; shape: TLShape }\n\t| { target: 'handle'; shape: TLShape; handle: TLHandle }\n\t| { target: 'overlay'; overlay: TLOverlay; shape?: undefined }\n\n/** @public */\nexport type TLPointerEventName =\n\t| 'pointer_down'\n\t| 'pointer_move'\n\t| 'long_press'\n\t| 'pointer_up'\n\t| 'right_click'\n\t| 'middle_click'\n\n/** @public */\nexport type TLCLickEventName = 'double_click' | 'triple_click' | 'quadruple_click'\n\n/** @public */\nexport type TLPinchEventName = 'pinch_start' | 'pinch' | 'pinch_end'\n\n/** @public */\nexport type TLKeyboardEventName = 'key_down' | 'key_up' | 'key_repeat'\n\n/** @public */\nexport type TLEventName =\n\t| TLPointerEventName\n\t| TLCLickEventName\n\t| TLPinchEventName\n\t| TLKeyboardEventName\n\t| 'wheel'\n\t| 'cancel'\n\t| 'complete'\n\t| 'interrupt'\n\t| 'tick'\n\n/** @public */\nexport interface TLBaseEventInfo {\n\ttype: UiEventType\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n\taccelKey: boolean\n}\n\n/** @public */\nexport type TLPointerEventInfo = TLBaseEventInfo & {\n\ttype: 'pointer'\n\tname: TLPointerEventName\n\t// The pointer position in client space, i.e. clientX / clientY\n\tpoint: VecLike\n\tpointerId: number\n\tbutton: number\n\tisPen: boolean\n} & TLPointerEventTarget\n\n/** @public */\nexport type TLClickEventInfo = TLBaseEventInfo & {\n\ttype: 'click'\n\tname: TLCLickEventName\n\tpoint: VecLike\n\tpointerId: number\n\tbutton: number\n\tphase: 'down' | 'up' | 'settle'\n} & TLPointerEventTarget\n\n/** @public */\nexport type TLKeyboardEventInfo = TLBaseEventInfo & {\n\ttype: 'keyboard'\n\tname: TLKeyboardEventName\n\tkey: string\n\tcode: string\n}\n\n/** @public */\nexport type TLPinchEventInfo = TLBaseEventInfo & {\n\ttype: 'pinch'\n\tname: TLPinchEventName\n\tpoint: VecModel\n\tdelta: VecModel\n}\n\n/** @public */\nexport type TLWheelEventInfo = TLBaseEventInfo & {\n\ttype: 'wheel'\n\tname: 'wheel'\n\tdelta: VecModel\n\tpoint: VecModel\n}\n\n/** @public */\nexport interface TLCancelEventInfo {\n\ttype: 'misc'\n\tname: 'cancel'\n}\n/** @public */\nexport interface TLCompleteEventInfo {\n\ttype: 'misc'\n\tname: 'complete'\n}\n/** @public */\nexport interface TLInterruptEventInfo {\n\ttype: 'misc'\n\tname: 'interrupt'\n}\n/** @public */\nexport interface TLTickEventInfo {\n\ttype: 'misc'\n\tname: 'tick'\n\telapsed: number\n}\n\n/** @public */\nexport type TLEventInfo =\n\t| TLPointerEventInfo\n\t| TLClickEventInfo\n\t| TLKeyboardEventInfo\n\t| TLPinchEventInfo\n\t| TLWheelEventInfo\n\t| TLCancelEventInfo\n\t| TLCompleteEventInfo\n\t| TLInterruptEventInfo\n\t| TLTickEventInfo\n\n/** @public */\nexport type TLPointerEvent = (info: TLPointerEventInfo) => void\n/** @public */\nexport type TLClickEvent = (info: TLClickEventInfo) => void\n/** @public */\nexport type TLKeyboardEvent = (info: TLKeyboardEventInfo) => void\n/** @public */\nexport type TLPinchEvent = (info: TLPinchEventInfo) => void\n/** @public */\nexport type TLWheelEvent = (info: TLWheelEventInfo) => void\n/** @public */\nexport type TLCancelEvent = (info: TLCancelEventInfo) => void\n/** @public */\nexport type TLCompleteEvent = (info: TLCompleteEventInfo) => void\n/** @public */\nexport type TLInterruptEvent = (info: TLInterruptEventInfo) => void\n/** @public */\nexport type TLTickEvent = (info: TLTickEventInfo) => void\n\n/** @public */\nexport type UiEvent =\n\t| TLPointerEvent\n\t| TLClickEvent\n\t| TLKeyboardEvent\n\t| TLPinchEvent\n\t| TLCancelEvent\n\t| TLCompleteEvent\n\n/** @public */\nexport type TLEnterEventHandler = (info: any, from: string) => void\n/** @public */\nexport type TLExitEventHandler = (info: any, to: string) => void\n\n/** @public */\nexport interface TLEventHandlers {\n\tonPointerDown: TLPointerEvent\n\tonPointerMove: TLPointerEvent\n\tonLongPress: TLPointerEvent\n\tonRightClick: TLPointerEvent\n\tonDoubleClick: TLClickEvent\n\tonTripleClick: TLClickEvent\n\tonQuadrupleClick: TLClickEvent\n\tonMiddleClick: TLPointerEvent\n\tonPointerUp: TLPointerEvent\n\tonKeyDown: TLKeyboardEvent\n\tonKeyUp: TLKeyboardEvent\n\tonKeyRepeat: TLKeyboardEvent\n\tonWheel: TLWheelEvent\n\tonCancel: TLCancelEvent\n\tonComplete: TLCompleteEvent\n\tonInterrupt: TLInterruptEvent\n\tonTick: TLTickEvent\n}\n\n/** @public */\nexport const EVENT_NAME_MAP: Record<\n\tExclude<TLEventName, TLPinchEventName>,\n\tkeyof TLEventHandlers\n> = {\n\twheel: 'onWheel',\n\tpointer_down: 'onPointerDown',\n\tpointer_move: 'onPointerMove',\n\tlong_press: 'onLongPress',\n\tpointer_up: 'onPointerUp',\n\tright_click: 'onRightClick',\n\tmiddle_click: 'onMiddleClick',\n\tkey_down: 'onKeyDown',\n\tkey_up: 'onKeyUp',\n\tkey_repeat: 'onKeyRepeat',\n\tcancel: 'onCancel',\n\tcomplete: 'onComplete',\n\tinterrupt: 'onInterrupt',\n\tdouble_click: 'onDoubleClick',\n\ttriple_click: 'onTripleClick',\n\tquadruple_click: 'onQuadrupleClick',\n\ttick: 'onTick',\n}\n"],
|
|
5
|
+
"mappings": "AA8LO,MAAM,iBAGT;AAAA,EACH,OAAO;AAAA,EACP,cAAc;AAAA,EACd,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,MAAM;AACP;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FileHelpers, assert, fetch } from "@tldraw/utils";
|
|
1
|
+
import { FileHelpers, LruCache, assert, fetch } from "@tldraw/utils";
|
|
2
2
|
function fetchCache(cb, init) {
|
|
3
|
-
const cache =
|
|
3
|
+
const cache = new LruCache(100);
|
|
4
4
|
return async function fetchCached(url) {
|
|
5
5
|
const existing = cache.get(url);
|
|
6
6
|
if (existing) return existing;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/exports/fetchCache.ts"],
|
|
4
|
-
"sourcesContent": ["import { FileHelpers, assert, fetch } from '@tldraw/utils'\n\
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa,QAAQ,aAAa;
|
|
4
|
+
"sourcesContent": ["import { FileHelpers, LruCache, assert, fetch } from '@tldraw/utils'\n\nexport function fetchCache<T>(cb: (response: Response) => Promise<T>, init?: RequestInit) {\n\tconst cache = new LruCache<string, Promise<T | null>>(100)\n\n\treturn async function fetchCached(url: string): Promise<T | null> {\n\t\tconst existing = cache.get(url)\n\t\tif (existing) return existing\n\n\t\tconst promise = (async () => {\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(url, init)\n\t\t\t\tassert(response.ok)\n\t\t\t\treturn await cb(response)\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err)\n\t\t\t\treturn null\n\t\t\t}\n\t\t})()\n\t\tcache.set(url, promise)\n\t\treturn promise\n\t}\n}\n\nexport const resourceToDataUrl = fetchCache(async (response) => {\n\treturn await FileHelpers.blobToDataUrl(await response.blob())\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa,UAAU,QAAQ,aAAa;AAE9C,SAAS,WAAc,IAAwC,MAAoB;AACzF,QAAM,QAAQ,IAAI,SAAoC,GAAG;AAEzD,SAAO,eAAe,YAAY,KAAgC;AACjE,UAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,QAAI,SAAU,QAAO;AAErB,UAAM,WAAW,YAAY;AAC5B,UAAI;AACH,cAAM,WAAW,MAAM,MAAM,KAAK,IAAI;AACtC,eAAO,SAAS,EAAE;AAClB,eAAO,MAAM,GAAG,QAAQ;AAAA,MACzB,SAAS,KAAK;AACb,gBAAQ,MAAM,GAAG;AACjB,eAAO;AAAA,MACR;AAAA,IACD,GAAG;AACH,UAAM,IAAI,KAAK,OAAO;AACtB,WAAO;AAAA,EACR;AACD;AAEO,MAAM,oBAAoB,WAAW,OAAO,aAAa;AAC/D,SAAO,MAAM,YAAY,cAAc,MAAM,SAAS,KAAK,CAAC;AAC7D,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/EditorComponentsContext.tsx"],
|
|
4
|
-
"sourcesContent": ["import { ComponentType, RefAttributes, createContext, useContext } from 'react'\nimport type {
|
|
5
|
-
"mappings": "AAAA,SAAuC,eAAe,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { ComponentType, RefAttributes, createContext, useContext } from 'react'\nimport type { TLCanvasComponentProps } from '../components/default-components/DefaultCanvas'\nimport type { TLErrorFallbackComponent } from '../components/default-components/DefaultErrorFallback'\nimport type { TLGridProps } from '../components/default-components/DefaultGrid'\nimport type { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'\nimport type { TLShapeErrorFallbackComponent } from '../components/default-components/DefaultShapeErrorFallback'\nimport type { TLShapeWrapperProps } from '../components/default-components/DefaultShapeWrapper'\n\n/** @public */\nexport interface TLEditorComponents {\n\tBackground?: ComponentType | null\n\tCanvas?: ComponentType<TLCanvasComponentProps> | null\n\tGrid?: ComponentType<TLGridProps> | null\n\tInFrontOfTheCanvas?: ComponentType | null\n\tLoadingScreen?: ComponentType | null\n\tOnTheCanvas?: ComponentType | null\n\tSelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null\n\tShapeWrapper?: ComponentType<TLShapeWrapperProps & RefAttributes<HTMLDivElement>> | null\n\tSpinner?: ComponentType<React.SVGProps<SVGSVGElement>> | null\n\tSvgDefs?: ComponentType | null\n\n\t// These will always have defaults\n\tErrorFallback?: TLErrorFallbackComponent\n\tShapeErrorFallback?: TLShapeErrorFallbackComponent\n}\n\nexport const EditorComponentsContext = createContext<null | Required<TLEditorComponents>>(null)\n\n/** @public */\nexport function useEditorComponents() {\n\tconst components = useContext(EditorComponentsContext)\n\tif (!components) {\n\t\tthrow new Error('useEditorComponents must be used inside of <EditorComponentsProvider />')\n\t}\n\treturn components\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAuC,eAAe,kBAAkB;AA0BjE,MAAM,0BAA0B,cAAmD,IAAI;AAGvF,SAAS,sBAAsB;AACrC,QAAM,aAAa,WAAW,uBAAuB;AACrD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,MAAM,yEAAyE;AAAA,EAC1F;AACA,SAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -133,9 +133,9 @@ function useCanvasEvents() {
|
|
|
133
133
|
}
|
|
134
134
|
function onContextMenu(e) {
|
|
135
135
|
if (!editor.options.rightClickPanning) return;
|
|
136
|
-
if (e.nativeEvent.isTrusted)
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
if (!e.nativeEvent.isTrusted) return;
|
|
137
|
+
if (e.button !== 2 || e.ctrlKey) return;
|
|
138
|
+
preventDefault(e);
|
|
139
139
|
}
|
|
140
140
|
return {
|
|
141
141
|
onPointerDown,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { tlenv } from '../globals/environment'\nimport {\n\telementShouldCaptureKeys,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst ownerDocument = editor.getContainerDocument()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\n\t\t\t\t// With right-click panning disabled, fire right_click on press and let the\n\t\t\t\t// native contextmenu through so the menu opens at the pointer-down location.\n\t\t\t\tif (e.button === 2 && !editor.options.rightClickPanning) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tconst rightClickPanning = editor.options.rightClickPanning\n\t\t\t\t// Check before dispatch (which resets isPanning)\n\t\t\t\tconst wasRightClickPanning =\n\t\t\t\t\trightClickPanning && e.button === 2 && editor.inputs.getIsPanning()\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\n\t\t\t\t// Static right-click: fire contextmenu at the pointer-up location\n\t\t\t\tif (rightClickPanning && e.button === 2 && !wasRightClickPanning) {\n\t\t\t\t\tconst contextMenuEvent = new PointerEvent('contextmenu', {\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\t\tbutton: 2,\n\t\t\t\t\t\tbuttons: 0,\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tpointerType: e.pointerType,\n\t\t\t\t\t\tisPrimary: e.isPrimary,\n\t\t\t\t\t})\n\t\t\t\t\te.currentTarget.dispatchEvent(contextMenuEvent)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tif (!(e.target instanceof editor.getContainerWindow().HTMLElement)) return\n\n\t\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\t\tif (\n\t\t\t\t\t// if the target is not inside the editing shape\n\t\t\t\t\t!(editingShapeId && e.target.closest(`[data-shape-id=\"${editingShapeId}\"]`)) &&\n\t\t\t\t\t// and the target is not an clickable element\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\t// and the target is not an editable element\n\t\t\t\t\t!elementShouldCaptureKeys(e.target, false)\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t\te.stopPropagation()\n\n\t\t\t\tconst pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY })\n\n\t\t\t\t// Call the custom onDropOnCanvas callback if provided\n\t\t\t\tif (editor.options.experimental__onDropOnCanvas) {\n\t\t\t\t\tconst handled = editor.options.experimental__onDropOnCanvas({\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t\tevent: e,\n\t\t\t\t\t})\n\t\t\t\t\tif (handled) return\n\t\t\t\t}\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\te.stopPropagation()\n\t\t\t}\n\n\t\t\tfunction onContextMenu(e: React.MouseEvent) {\n\t\t\t\t// With right-click panning disabled, let the native contextmenu through so the\n\t\t\t\t// menu opens on press.\n\t\t\t\tif (!editor.options.rightClickPanning) return\n\t\t\t\t// Synthetic events \u2014 our own dispatch from onPointerUp, or tests using\n\t\t\t\t// fireEvent.contextMenu \u2014 pass through so Radix can open the menu.
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { tlenv } from '../globals/environment'\nimport {\n\telementShouldCaptureKeys,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst ownerDocument = editor.getContainerDocument()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\n\t\t\t\t// With right-click panning disabled, fire right_click on press and let the\n\t\t\t\t// native contextmenu through so the menu opens at the pointer-down location.\n\t\t\t\tif (e.button === 2 && !editor.options.rightClickPanning) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tconst rightClickPanning = editor.options.rightClickPanning\n\t\t\t\t// Check before dispatch (which resets isPanning)\n\t\t\t\tconst wasRightClickPanning =\n\t\t\t\t\trightClickPanning && e.button === 2 && editor.inputs.getIsPanning()\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\n\t\t\t\t// Static right-click: fire contextmenu at the pointer-up location\n\t\t\t\tif (rightClickPanning && e.button === 2 && !wasRightClickPanning) {\n\t\t\t\t\tconst contextMenuEvent = new PointerEvent('contextmenu', {\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\t\tbutton: 2,\n\t\t\t\t\t\tbuttons: 0,\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tpointerType: e.pointerType,\n\t\t\t\t\t\tisPrimary: e.isPrimary,\n\t\t\t\t\t})\n\t\t\t\t\te.currentTarget.dispatchEvent(contextMenuEvent)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tif (!(e.target instanceof editor.getContainerWindow().HTMLElement)) return\n\n\t\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\t\tif (\n\t\t\t\t\t// if the target is not inside the editing shape\n\t\t\t\t\t!(editingShapeId && e.target.closest(`[data-shape-id=\"${editingShapeId}\"]`)) &&\n\t\t\t\t\t// and the target is not an clickable element\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\t// and the target is not an editable element\n\t\t\t\t\t!elementShouldCaptureKeys(e.target, false)\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t\te.stopPropagation()\n\n\t\t\t\tconst pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY })\n\n\t\t\t\t// Call the custom onDropOnCanvas callback if provided\n\t\t\t\tif (editor.options.experimental__onDropOnCanvas) {\n\t\t\t\t\tconst handled = editor.options.experimental__onDropOnCanvas({\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t\tevent: e,\n\t\t\t\t\t})\n\t\t\t\t\tif (handled) return\n\t\t\t\t}\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\te.stopPropagation()\n\t\t\t}\n\n\t\t\tfunction onContextMenu(e: React.MouseEvent) {\n\t\t\t\t// With right-click panning disabled, let the native contextmenu through so the\n\t\t\t\t// menu opens on press.\n\t\t\t\tif (!editor.options.rightClickPanning) return\n\t\t\t\t// Synthetic events \u2014 our own dispatch from onPointerUp, or tests using\n\t\t\t\t// fireEvent.contextMenu \u2014 pass through so Radix can open the menu.\n\t\t\t\tif (!e.nativeEvent.isTrusted) return\n\t\t\t\t// Only suppress the native browser contextmenu when it follows a real\n\t\t\t\t// right-click (button=2 with no ctrl modifier). For those, our pointer\n\t\t\t\t// handling has already decided what to do (either we'll dispatch a\n\t\t\t\t// synthetic contextmenu on pointerup to open the menu at the release\n\t\t\t\t// position, or we panned and don't want a menu at all).\n\t\t\t\t//\n\t\t\t\t// Other contextmenu sources must reach Radix so the menu opens:\n\t\t\t\t// - ctrl+click on macOS (button=0, or button=2 with ctrlKey=true)\n\t\t\t\t// - long-press on touch devices (button=0, pointerType=touch)\n\t\t\t\tif (e.button !== 2 || e.ctrlKey) return\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t\tonContextMenu,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\teditor.markEventAsHandled(e)\n\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\t// Specifically, in local mode (non-https) mode, iOS does not `useCoalescedEvents`\n\t\t\t// so it appears like the ink is working locally, when really it's just that `useCoalescedEvents`\n\t\t\t// is disabled. The intent here is to have `useCoalescedEvents` disabled for iOS.\n\t\t\tconst events =\n\t\t\t\t!tlenv.isIos && currentTool.useCoalescedEvents && e.getCoalescedEvents\n\t\t\t\t\t? e.getCoalescedEvents()\n\t\t\t\t\t: [e]\n\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\townerDocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\townerDocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool, ownerDocument])\n\n\treturn events\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["events"]
|
|
7
7
|
}
|
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { DefaultBackground } from "../components/default-components/DefaultBackground.mjs";
|
|
4
|
-
import { DefaultBrush } from "../components/default-components/DefaultBrush.mjs";
|
|
5
4
|
import { DefaultCanvas } from "../components/default-components/DefaultCanvas.mjs";
|
|
6
|
-
import { DefaultCollaboratorHint } from "../components/default-components/DefaultCollaboratorHint.mjs";
|
|
7
|
-
import { DefaultCursor } from "../components/default-components/DefaultCursor.mjs";
|
|
8
5
|
import { DefaultErrorFallback } from "../components/default-components/DefaultErrorFallback.mjs";
|
|
9
6
|
import { DefaultGrid } from "../components/default-components/DefaultGrid.mjs";
|
|
10
|
-
import { DefaultHandle } from "../components/default-components/DefaultHandle.mjs";
|
|
11
|
-
import { DefaultHandles } from "../components/default-components/DefaultHandles.mjs";
|
|
12
7
|
import { DefaultLoadingScreen } from "../components/default-components/DefaultLoadingScreen.mjs";
|
|
13
|
-
import { DefaultScribble } from "../components/default-components/DefaultScribble.mjs";
|
|
14
|
-
import { DefaultSelectionForeground } from "../components/default-components/DefaultSelectionForeground.mjs";
|
|
15
8
|
import { DefaultShapeErrorFallback } from "../components/default-components/DefaultShapeErrorFallback.mjs";
|
|
16
|
-
import { DefaultShapeIndicator } from "../components/default-components/DefaultShapeIndicator.mjs";
|
|
17
|
-
import { DefaultShapeIndicatorErrorFallback } from "../components/default-components/DefaultShapeIndicatorErrorFallback.mjs";
|
|
18
|
-
import { DefaultShapeIndicators } from "../components/default-components/DefaultShapeIndicators.mjs";
|
|
19
9
|
import { DefaultShapeWrapper } from "../components/default-components/DefaultShapeWrapper.mjs";
|
|
20
|
-
import { DefaultSnapIndicator } from "../components/default-components/DefaultSnapIndictor.mjs";
|
|
21
10
|
import { DefaultSpinner } from "../components/default-components/DefaultSpinner.mjs";
|
|
22
11
|
import { DefaultSvgDefs } from "../components/default-components/DefaultSvgDefs.mjs";
|
|
23
12
|
import { EditorComponentsContext } from "./EditorComponentsContext.mjs";
|
|
@@ -31,34 +20,17 @@ function EditorComponentsProvider({
|
|
|
31
20
|
const value = useMemo(
|
|
32
21
|
() => ({
|
|
33
22
|
Background: DefaultBackground,
|
|
34
|
-
Brush: DefaultBrush,
|
|
35
23
|
Canvas: DefaultCanvas,
|
|
36
|
-
CollaboratorBrush: DefaultBrush,
|
|
37
|
-
CollaboratorCursor: DefaultCursor,
|
|
38
|
-
CollaboratorHint: DefaultCollaboratorHint,
|
|
39
|
-
CollaboratorScribble: DefaultScribble,
|
|
40
|
-
CollaboratorShapeIndicator: DefaultShapeIndicator,
|
|
41
|
-
Cursor: DefaultCursor,
|
|
42
24
|
Grid: DefaultGrid,
|
|
43
|
-
Handle: DefaultHandle,
|
|
44
|
-
Handles: DefaultHandles,
|
|
45
25
|
InFrontOfTheCanvas: null,
|
|
46
26
|
LoadingScreen: DefaultLoadingScreen,
|
|
47
27
|
OnTheCanvas: null,
|
|
48
|
-
Overlays: null,
|
|
49
|
-
Scribble: DefaultScribble,
|
|
50
28
|
SelectionBackground: null,
|
|
51
|
-
SelectionForeground: DefaultSelectionForeground,
|
|
52
|
-
ShapeIndicator: DefaultShapeIndicator,
|
|
53
|
-
ShapeIndicators: DefaultShapeIndicators,
|
|
54
29
|
ShapeWrapper: DefaultShapeWrapper,
|
|
55
|
-
SnapIndicator: DefaultSnapIndicator,
|
|
56
30
|
Spinner: DefaultSpinner,
|
|
57
31
|
SvgDefs: DefaultSvgDefs,
|
|
58
|
-
ZoomBrush: DefaultBrush,
|
|
59
32
|
ErrorFallback: DefaultErrorFallback,
|
|
60
33
|
ShapeErrorFallback: DefaultShapeErrorFallback,
|
|
61
|
-
ShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback,
|
|
62
34
|
..._overrides
|
|
63
35
|
}),
|
|
64
36
|
[_overrides]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useEditorComponents.tsx"],
|
|
4
|
-
"sourcesContent": ["import { ReactNode, useMemo } from 'react'\nimport { DefaultBackground } from '../components/default-components/DefaultBackground'\nimport {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { ReactNode, useMemo } from 'react'\nimport { DefaultBackground } from '../components/default-components/DefaultBackground'\nimport { DefaultCanvas } from '../components/default-components/DefaultCanvas'\nimport { DefaultErrorFallback } from '../components/default-components/DefaultErrorFallback'\nimport { DefaultGrid } from '../components/default-components/DefaultGrid'\nimport { DefaultLoadingScreen } from '../components/default-components/DefaultLoadingScreen'\nimport { DefaultShapeErrorFallback } from '../components/default-components/DefaultShapeErrorFallback'\nimport { DefaultShapeWrapper } from '../components/default-components/DefaultShapeWrapper'\nimport { DefaultSpinner } from '../components/default-components/DefaultSpinner'\nimport { DefaultSvgDefs } from '../components/default-components/DefaultSvgDefs'\nimport { EditorComponentsContext } from './EditorComponentsContext'\nimport type { TLEditorComponents } from './EditorComponentsContext'\nimport { useShallowObjectIdentity } from './useIdentity'\n\nexport { useEditorComponents } from './EditorComponentsContext'\nexport type { TLEditorComponents } from './EditorComponentsContext'\n\ninterface ComponentsContextProviderProps {\n\toverrides?: TLEditorComponents\n\tchildren: ReactNode\n}\n\nexport function EditorComponentsProvider({\n\toverrides = {},\n\tchildren,\n}: ComponentsContextProviderProps) {\n\tconst _overrides = useShallowObjectIdentity(overrides)\n\tconst value = useMemo(\n\t\t(): Required<TLEditorComponents> => ({\n\t\t\tBackground: DefaultBackground,\n\t\t\tCanvas: DefaultCanvas,\n\t\t\tGrid: DefaultGrid,\n\t\t\tInFrontOfTheCanvas: null,\n\t\t\tLoadingScreen: DefaultLoadingScreen,\n\t\t\tOnTheCanvas: null,\n\t\t\tSelectionBackground: null,\n\t\t\tShapeWrapper: DefaultShapeWrapper,\n\t\t\tSpinner: DefaultSpinner,\n\t\t\tSvgDefs: DefaultSvgDefs,\n\n\t\t\tErrorFallback: DefaultErrorFallback,\n\t\t\tShapeErrorFallback: DefaultShapeErrorFallback,\n\n\t\t\t..._overrides,\n\t\t}),\n\t\t[_overrides]\n\t)\n\n\treturn (\n\t\t<EditorComponentsContext.Provider value={value}>{children}</EditorComponentsContext.Provider>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "AAiDE;AAjDF,SAAoB,eAAe;AACnC,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAC1C,SAAS,2BAA2B;AACpC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,+BAA+B;AAExC,SAAS,gCAAgC;AAEzC,SAAS,2BAA2B;AAQ7B,SAAS,yBAAyB;AAAA,EACxC,YAAY,CAAC;AAAA,EACb;AACD,GAAmC;AAClC,QAAM,aAAa,yBAAyB,SAAS;AACrD,QAAM,QAAQ;AAAA,IACb,OAAqC;AAAA,MACpC,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,SAAS;AAAA,MACT,SAAS;AAAA,MAET,eAAe;AAAA,MACf,oBAAoB;AAAA,MAEpB,GAAG;AAAA,IACJ;AAAA,IACA,CAAC,UAAU;AAAA,EACZ;AAEA,SACC,oBAAC,wBAAwB,UAAxB,EAAiC,OAAe,UAAS;AAE5D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,55 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useEffect } from "react";
|
|
3
|
-
import {
|
|
4
|
-
getCollaboratorStateFromElapsedTime,
|
|
5
|
-
shouldShowCollaborator
|
|
6
|
-
} from "../utils/collaboratorState.mjs";
|
|
1
|
+
import { useComputed, useValue } from "@tldraw/state-react";
|
|
7
2
|
import { uniq } from "../utils/uniq.mjs";
|
|
8
3
|
import { useEditor } from "./useEditor.mjs";
|
|
9
|
-
function setsEqual(a, b) {
|
|
10
|
-
if (a.size !== b.size) return false;
|
|
11
|
-
for (const item of a) {
|
|
12
|
-
if (!b.has(item)) return false;
|
|
13
|
-
}
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
4
|
function usePeerIds() {
|
|
17
5
|
const editor = useEditor();
|
|
18
6
|
const $userIds = useComputed(
|
|
19
7
|
"userIds",
|
|
20
|
-
() => uniq(editor.
|
|
8
|
+
() => uniq(editor.getVisibleCollaborators().map((p) => p.userId)).sort(),
|
|
21
9
|
{ isEqual: (a, b) => a.join(",") === b.join?.(",") },
|
|
22
10
|
[editor]
|
|
23
11
|
);
|
|
24
12
|
return useValue($userIds);
|
|
25
13
|
}
|
|
26
|
-
function useActivePeerIds$() {
|
|
27
|
-
const $time = useAtom("peerIdsTime", Date.now());
|
|
28
|
-
const editor = useEditor();
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
const interval = editor.timers.setInterval(() => {
|
|
31
|
-
$time.set(Date.now());
|
|
32
|
-
}, editor.options.collaboratorCheckIntervalMs);
|
|
33
|
-
return () => clearInterval(interval);
|
|
34
|
-
}, [editor, $time]);
|
|
35
|
-
return useComputed(
|
|
36
|
-
"activePeerIds",
|
|
37
|
-
() => {
|
|
38
|
-
const now = $time.get();
|
|
39
|
-
return new Set(
|
|
40
|
-
editor.getCollaborators().filter((p) => {
|
|
41
|
-
const elapsed = Math.max(0, now - (p.lastActivityTimestamp ?? Infinity));
|
|
42
|
-
const state = getCollaboratorStateFromElapsedTime(editor, elapsed);
|
|
43
|
-
return shouldShowCollaborator(editor, p, state);
|
|
44
|
-
}).map((p) => p.userId)
|
|
45
|
-
);
|
|
46
|
-
},
|
|
47
|
-
{ isEqual: setsEqual },
|
|
48
|
-
[editor]
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
14
|
export {
|
|
52
|
-
useActivePeerIds$,
|
|
53
15
|
usePeerIds
|
|
54
16
|
};
|
|
55
17
|
//# sourceMappingURL=usePeerIds.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/usePeerIds.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { useComputed, useValue } from '@tldraw/state-react'\nimport { uniq } from '../utils/uniq'\nimport { useEditor } from './useEditor'\n\n/**\n * Reactive list of peer user IDs for collaborators currently shown in the UI.\n * Mirrors {@link Editor.getVisibleCollaborators} \u2014 peers fade out as they\n * transition to idle/inactive, without requiring a manual re-render.\n *\n * @returns The list of peer UserIDs\n * @public\n */\nexport function usePeerIds() {\n\tconst editor = useEditor()\n\n\tconst $userIds = useComputed(\n\t\t'userIds',\n\t\t() => uniq(editor.getVisibleCollaborators().map((p) => p.userId)).sort(),\n\t\t{ isEqual: (a, b) => a.join(',') === b.join?.(',') },\n\t\t[editor]\n\t)\n\n\treturn useValue($userIds)\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa,gBAAgB;AACtC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAUnB,SAAS,aAAa;AAC5B,QAAM,SAAS,UAAU;AAEzB,QAAM,WAAW;AAAA,IAChB;AAAA,IACA,MAAM,KAAK,OAAO,wBAAwB,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK;AAAA,IACvE,EAAE,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,GAAG,EAAE;AAAA,IACnD,CAAC,MAAM;AAAA,EACR;AAEA,SAAO,SAAS,QAAQ;AACzB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -21,8 +21,9 @@ function ShapeCullingProvider({ children }) {
|
|
|
21
21
|
containersRef.current.delete(id);
|
|
22
22
|
}, []);
|
|
23
23
|
const updateCulling = useCallback((culledShapes) => {
|
|
24
|
+
let shouldBeCulled;
|
|
24
25
|
for (const [id, entry] of containersRef.current) {
|
|
25
|
-
|
|
26
|
+
shouldBeCulled = culledShapes.has(id);
|
|
26
27
|
if (shouldBeCulled !== entry.isCulled) {
|
|
27
28
|
const display = shouldBeCulled ? "none" : "block";
|
|
28
29
|
setStyleProperty(entry.container, "display", display);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useShapeCulling.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLShapeId } from '@tldraw/tlschema'\nimport { createContext, useCallback, useContext, useMemo, useRef } from 'react'\nimport { setStyleProperty } from '../utils/dom'\n\ninterface ShapeContainerEntry {\n\tcontainer: HTMLDivElement\n\tbgContainer: HTMLDivElement | null\n\tisCulled: boolean\n}\n\ninterface ShapeCullingContextValue {\n\tregister(\n\t\tid: TLShapeId,\n\t\tcontainer: HTMLDivElement,\n\t\tbgContainer: HTMLDivElement | null,\n\t\tisCulled: boolean\n\t): void\n\tunregister(id: TLShapeId): void\n\tupdateCulling(culledShapes: Set<TLShapeId>): void\n}\n\nconst ShapeCullingContext = createContext<ShapeCullingContextValue | null>(null)\n\n/** @internal */\nexport interface ShapeCullingProviderProps {\n\tchildren: React.ReactNode\n}\n\n/**\n * Provides centralized culling management for shape containers.\n * This allows a single reactor to update all shape display states\n * instead of each shape having its own subscription.\n *\n * @internal\n */\nexport function ShapeCullingProvider({ children }: ShapeCullingProviderProps) {\n\tconst containersRef = useRef(new Map<TLShapeId, ShapeContainerEntry>())\n\n\tconst register = useCallback(\n\t\t(\n\t\t\tid: TLShapeId,\n\t\t\tcontainer: HTMLDivElement,\n\t\t\tbgContainer: HTMLDivElement | null,\n\t\t\tisCulled: boolean\n\t\t) => {\n\t\t\tconst display = isCulled ? 'none' : 'block'\n\t\t\tsetStyleProperty(container, 'display', display)\n\t\t\tsetStyleProperty(bgContainer, 'display', display)\n\n\t\t\tcontainersRef.current.set(id, {\n\t\t\t\tcontainer,\n\t\t\t\tbgContainer,\n\t\t\t\tisCulled,\n\t\t\t})\n\t\t},\n\t\t[]\n\t)\n\n\tconst unregister = useCallback((id: TLShapeId) => {\n\t\tcontainersRef.current.delete(id)\n\t}, [])\n\n\tconst updateCulling = useCallback((culledShapes: Set<TLShapeId>) => {\n\t\tfor (const [id, entry] of containersRef.current) {\n\t\t\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { TLShapeId } from '@tldraw/tlschema'\nimport { createContext, useCallback, useContext, useMemo, useRef } from 'react'\nimport { setStyleProperty } from '../utils/dom'\n\ninterface ShapeContainerEntry {\n\tcontainer: HTMLDivElement\n\tbgContainer: HTMLDivElement | null\n\tisCulled: boolean\n}\n\ninterface ShapeCullingContextValue {\n\tregister(\n\t\tid: TLShapeId,\n\t\tcontainer: HTMLDivElement,\n\t\tbgContainer: HTMLDivElement | null,\n\t\tisCulled: boolean\n\t): void\n\tunregister(id: TLShapeId): void\n\tupdateCulling(culledShapes: Set<TLShapeId>): void\n}\n\nconst ShapeCullingContext = createContext<ShapeCullingContextValue | null>(null)\n\n/** @internal */\nexport interface ShapeCullingProviderProps {\n\tchildren: React.ReactNode\n}\n\n/**\n * Provides centralized culling management for shape containers.\n * This allows a single reactor to update all shape display states\n * instead of each shape having its own subscription.\n *\n * @internal\n */\nexport function ShapeCullingProvider({ children }: ShapeCullingProviderProps) {\n\tconst containersRef = useRef(new Map<TLShapeId, ShapeContainerEntry>())\n\n\tconst register = useCallback(\n\t\t(\n\t\t\tid: TLShapeId,\n\t\t\tcontainer: HTMLDivElement,\n\t\t\tbgContainer: HTMLDivElement | null,\n\t\t\tisCulled: boolean\n\t\t) => {\n\t\t\tconst display = isCulled ? 'none' : 'block'\n\t\t\tsetStyleProperty(container, 'display', display)\n\t\t\tsetStyleProperty(bgContainer, 'display', display)\n\n\t\t\tcontainersRef.current.set(id, {\n\t\t\t\tcontainer,\n\t\t\t\tbgContainer,\n\t\t\t\tisCulled,\n\t\t\t})\n\t\t},\n\t\t[]\n\t)\n\n\tconst unregister = useCallback((id: TLShapeId) => {\n\t\tcontainersRef.current.delete(id)\n\t}, [])\n\n\tconst updateCulling = useCallback((culledShapes: Set<TLShapeId>) => {\n\t\tlet shouldBeCulled: boolean\n\n\t\tfor (const [id, entry] of containersRef.current) {\n\t\t\tshouldBeCulled = culledShapes.has(id)\n\t\t\tif (shouldBeCulled !== entry.isCulled) {\n\t\t\t\tconst display = shouldBeCulled ? 'none' : 'block'\n\t\t\t\tsetStyleProperty(entry.container, 'display', display)\n\t\t\t\tsetStyleProperty(entry.bgContainer, 'display', display)\n\t\t\t\tentry.isCulled = shouldBeCulled\n\t\t\t}\n\t\t}\n\t}, [])\n\n\tconst value = useMemo(\n\t\t() => ({\n\t\t\tregister,\n\t\t\tunregister,\n\t\t\tupdateCulling,\n\t\t}),\n\t\t[register, unregister, updateCulling]\n\t)\n\n\treturn <ShapeCullingContext.Provider value={value}>{children}</ShapeCullingContext.Provider>\n}\n\n/**\n * Hook to access the shape culling context for container registration.\n *\n * @internal\n */\nexport function useShapeCulling(): ShapeCullingContextValue {\n\tconst context = useContext(ShapeCullingContext)\n\tif (!context) {\n\t\tthrow new Error('useShapeCulling must be used within ShapeCullingProvider')\n\t}\n\treturn context\n}\n"],
|
|
5
|
+
"mappings": "AAqFQ;AApFR,SAAS,eAAe,aAAa,YAAY,SAAS,cAAc;AACxE,SAAS,wBAAwB;AAmBjC,MAAM,sBAAsB,cAA+C,IAAI;AAcxE,SAAS,qBAAqB,EAAE,SAAS,GAA8B;AAC7E,QAAM,gBAAgB,OAAO,oBAAI,IAAoC,CAAC;AAEtE,QAAM,WAAW;AAAA,IAChB,CACC,IACA,WACA,aACA,aACI;AACJ,YAAM,UAAU,WAAW,SAAS;AACpC,uBAAiB,WAAW,WAAW,OAAO;AAC9C,uBAAiB,aAAa,WAAW,OAAO;AAEhD,oBAAc,QAAQ,IAAI,IAAI;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACF;AAEA,QAAM,aAAa,YAAY,CAAC,OAAkB;AACjD,kBAAc,QAAQ,OAAO,EAAE;AAAA,EAChC,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,YAAY,CAAC,iBAAiC;AACnE,QAAI;AAEJ,eAAW,CAAC,IAAI,KAAK,KAAK,cAAc,SAAS;AAChD,uBAAiB,aAAa,IAAI,EAAE;AACpC,UAAI,mBAAmB,MAAM,UAAU;AACtC,cAAM,UAAU,iBAAiB,SAAS;AAC1C,yBAAiB,MAAM,WAAW,WAAW,OAAO;AACpD,yBAAiB,MAAM,aAAa,WAAW,OAAO;AACtD,cAAM,WAAW;AAAA,MAClB;AAAA,IACD;AAAA,EACD,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACb,OAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA,CAAC,UAAU,YAAY,aAAa;AAAA,EACrC;AAEA,SAAO,oBAAC,oBAAoB,UAApB,EAA6B,OAAe,UAAS;AAC9D;AAOO,SAAS,kBAA4C;AAC3D,QAAM,UAAU,WAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACb,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC3E;AACA,SAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/lib/options.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/options.ts"],
|
|
4
|
-
"sourcesContent": ["import { Awaitable } from '@tldraw/utils'\nimport { ComponentType, Fragment } from 'react'\nimport { DEFAULT_CAMERA_OPTIONS } from './constants'\nimport type { Editor } from './editor/Editor'\nimport { TLContent } from './editor/types/clipboard-types'\nimport { TLExternalContent } from './editor/types/external-content'\nimport { TLCameraOptions } from './editor/types/misc-types'\nimport { VecLike } from './primitives/Vec'\nimport { TLDeepLinkOptions } from './utils/deepLinks'\nimport { TLTextOptions } from './utils/richText'\n\n/**\n * Identifies how a clipboard write was triggered (copy vs cut, keyboard vs menu).\n *\n * @public\n */\nexport interface TLClipboardWriteInfo {\n\treadonly operation: 'copy' | 'cut'\n\treadonly source: 'native' | 'menu'\n}\n\n/**\n * Raw clipboard paste payload, before tldraw parses clipboard contents into {@link TLExternalContent}.\n *\n * - `native-event`: from the `paste` event \u2014 `clipboardData` is available synchronously (unlike async\n * `navigator.clipboard.read()`).\n * - `clipboard-read`: from an explicit `navigator.clipboard.read()` call \u2014 only `ClipboardItem[]`\n * exists\n * (no `DataTransfer`).\n *\n * @public\n */\nexport type TLClipboardPasteRawInfo =\n\t| {\n\t\t\treadonly editor: Editor\n\t\t\treadonly source: 'native-event'\n\t\t\treadonly event: ClipboardEvent\n\t\t\treadonly clipboardData: DataTransfer | null\n\t\t\treadonly point: VecLike | undefined\n\t }\n\t| {\n\t\t\treadonly editor: Editor\n\t\t\treadonly source: 'clipboard-read'\n\t\t\treadonly clipboardItems: readonly ClipboardItem[]\n\t\t\treadonly point: VecLike | undefined\n\t }\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly uiDragDistanceSquared: number\n\treadonly uiCoarseDragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\t/**\n\t * How long (in milliseconds) to fade all laser scribbles after the session ends.\n\t * The total points across all scribbles will be removed proportionally over this duration.\n\t * Defaults to 500ms (0.5 seconds).\n\t */\n\treadonly laserFadeoutMs: number\n\treadonly maxExportDelayMs: number\n\treadonly tooltipDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.\n\t */\n\treadonly enableToolbarKeyboardShortcuts: boolean\n\t/**\n\t * The maximum number of fonts that will be loaded while blocking the main rendering of the\n\t * canvas. If there are more than this number of fonts needed, we'll just show the canvas right\n\t * away and let the fonts load in in the background.\n\t */\n\treadonly maxFontsToLoadBeforeRender: number\n\t/**\n\t * If you have a CSP policy that blocks inline styles, you can use this prop to provide a\n\t * nonce to use in the editor's styles.\n\t */\n\treadonly nonce: string | undefined\n\t/**\n\t * Branding name of the app, currently only used for adding aria-label for the application.\n\t */\n\treadonly branding?: string\n\t/**\n\t * Whether to use debounced zoom level for certain rendering optimizations. When true,\n\t * `editor.getEfficientZoomLevel()` returns a cached zoom value while the camera is moving,\n\t * reducing re-renders. When false, it always returns the current zoom level.\n\t */\n\treadonly debouncedZoom: boolean\n\t/**\n\t * The number of shapes that must be on the page for the debounced zoom level to be used.\n\t * Defaults to 500 shapes.\n\t */\n\treadonly debouncedZoomThreshold: number\n\t/**\n\t * Whether to allow spacebar panning. When true, the spacebar will pan the camera when held down.\n\t * When false, the spacebar will not pan the camera.\n\t */\n\treadonly spacebarPanning: boolean\n\t/**\n\t * Whether to allow right-click + drag to pan the camera. When true, right-click + drag pans the\n\t * camera and a static right-click opens the context menu at the release position. When false,\n\t * right-click opens the context menu on press (no drag-to-pan).\n\t */\n\treadonly rightClickPanning: boolean\n\t/**\n\t * The default padding (in pixels) used when zooming to fit content in the viewport.\n\t * This affects methods like `zoomToFit()`, `zoomToSelection()`, and `zoomToBounds()`.\n\t * The actual padding used is the minimum of this value and 28% of the viewport width.\n\t * Defaults to 128 pixels.\n\t */\n\treadonly zoomToFitPadding: number\n\t/**\n\t * The distance (in screen pixels) at which shapes snap to guides and other shapes.\n\t */\n\treadonly snapThreshold: number\n\t/**\n\t * Options for the editor's camera. These are the initial camera options.\n\t * Use {@link Editor.setCameraOptions} to update camera options at runtime.\n\t */\n\treadonly camera: Partial<TLCameraOptions>\n\t/**\n\t * Options for the editor's text rendering. These include TipTap configuration and\n\t * font handling. These are the initial text options and cannot be changed at runtime.\n\t */\n\treadonly text: TLTextOptions\n\t/**\n\t * Options for syncing the editor's camera state with the URL. Set to `true` to enable\n\t * with default options, or pass an options object to customize behavior.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Enable with defaults\n\t * <Tldraw options={{ deepLinks: true }} />\n\t *\n\t * // Enable with custom options\n\t * <Tldraw options={{ deepLinks: { param: 'd', debounceMs: 500 } }} />\n\t * ```\n\t */\n\treadonly deepLinks: true | TLDeepLinkOptions | undefined\n\t/**\n\t * Whether the quick-zoom brush preserves its screen-pixel size when the user\n\t * zooms the overview. When true, zooming in shrinks the target viewport (higher\n\t * return zoom); zooming out expands it. When false, the brush keeps the original\n\t * viewport's page dimensions regardless of overview zoom changes.\n\t */\n\treadonly quickZoomPreservesScreenBounds: boolean\n\t/**\n\t * Whether to use 2D canvas rendering for shape indicators. When true (default),\n\t * shapes that support it will render indicators on a 2D canvas for better\n\t * performance. When false, all indicators use legacy SVG rendering.\n\t */\n\treadonly useCanvasIndicators: boolean\n\t/**\n\t * Called before content is written to the clipboard during a copy or cut operation.\n\t * Receives the serialized content (shapes, bindings, assets) and can filter or transform\n\t * it before it reaches the clipboard.\n\t *\n\t * Return a modified `TLContent` object to change what is copied or cut. Return `false` to\n\t * cancel the clipboard write (for cut, the selected shapes are not removed). Return `void`\n\t * (or `undefined`) to pass through unchanged. You may return a `Promise` of those values if\n\t * the hook is async.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Filter out \"locked\" shapes from copy\n\t * onBeforeCopyToClipboard({ content, operation }) {\n\t * return {\n\t * ...content,\n\t * shapes: content.shapes.filter(s => !s.meta.locked),\n\t * rootShapeIds: content.rootShapeIds.filter(id =>\n\t * content.shapes.find(s => s.id === id && !s.meta.locked)\n\t * ),\n\t * }\n\t * }\n\t * ```\n\t */\n\tonBeforeCopyToClipboard?(\n\t\tinfo: { editor: Editor; content: TLContent } & TLClipboardWriteInfo\n\t): Awaitable<TLContent | false | void>\n\t/**\n\t * Called before pasted content is processed and shapes are created. Receives the parsed\n\t * external content from the clipboard and can filter, transform, or cancel it.\n\t *\n\t * Return `false` to cancel the paste. Return a modified content object to transform it.\n\t * Return `void` (or `undefined`) to pass through unchanged. You may return a `Promise` of\n\t * those values if the hook is async.\n\t *\n\t * This only fires for clipboard paste operations (keyboard shortcuts and menu actions),\n\t * not for file drops or programmatic `putExternalContent` calls.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Block pasting of image files\n\t * onBeforePasteFromClipboard({ content }) {\n\t * if (content.type === 'files') {\n\t * const nonImages = content.files.filter(f => !f.type.startsWith('image/'))\n\t * if (nonImages.length === 0) return false\n\t * return { ...content, files: nonImages }\n\t * }\n\t * }\n\t * ```\n\t */\n\tonBeforePasteFromClipboard?(info: {\n\t\teditor: Editor\n\t\tcontent: TLExternalContent<unknown>\n\t\tsource: 'native-event' | 'clipboard-read'\n\t\tpoint?: VecLike\n\t}): Awaitable<TLExternalContent<unknown> | false | void>\n\t/**\n\t * Called first for keyboard and menu paste, **before** tldraw handles or parses clipboard data\n\t * (and before {@link TldrawOptions.onBeforePasteFromClipboard}).\n\t *\n\t * Return `false` to cancel tldraw's default paste handling for this gesture (same convention as\n\t * {@link TldrawOptions.onBeforePasteFromClipboard}). Use this when you handle paste yourself from\n\t * raw clipboard data, or to block the gesture entirely. Return `void` (or `undefined`) to continue.\n\t */\n\tonClipboardPasteRaw?(info: TLClipboardPasteRawInfo): false | void\n\t/**\n\t * Called when content is dropped on the canvas. Provides the page position\n\t * where the drop occurred and the underlying drag event object.\n\t * Return true to prevent default drop handling (files, URLs, etc.)\n\t */\n\texperimental__onDropOnCanvas?(options: {\n\t\tpoint: VecLike\n\t\tevent: React.DragEvent<Element>\n\t}): boolean\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tuiDragDistanceSquared: 16, // 4 squared\n\t// it's really easy to accidentally drag from the toolbar on mobile, so we use a much larger\n\t// threshold than usual here to try and prevent accidental drags.\n\tuiCoarseDragDistanceSquared: 625, // 25 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tlaserFadeoutMs: 500,\n\tmaxExportDelayMs: 5000,\n\ttooltipDelayMs: 700,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n\tactionShortcutsLocation: 'swap',\n\tcreateTextOnCanvasDoubleClick: true,\n\texportProvider: Fragment,\n\tenableToolbarKeyboardShortcuts: true,\n\tmaxFontsToLoadBeforeRender: Infinity,\n\tnonce: undefined,\n\tdebouncedZoom: true,\n\tdebouncedZoomThreshold: 500,\n\tspacebarPanning: true,\n\trightClickPanning: true,\n\tzoomToFitPadding: 128,\n\tsnapThreshold: 8,\n\tcamera: DEFAULT_CAMERA_OPTIONS,\n\ttext: {},\n\tdeepLinks: undefined,\n\tuseCanvasIndicators: true,\n\tquickZoomPreservesScreenBounds: true,\n\tonBeforeCopyToClipboard: undefined,\n\tonBeforePasteFromClipboard: undefined,\n\tonClipboardPasteRaw: undefined,\n\texperimental__onDropOnCanvas: undefined,\n} as const satisfies TldrawOptions\n"],
|
|
5
|
-
"mappings": "AACA,SAAwB,gBAAgB;AACxC,SAAS,8BAA8B;
|
|
4
|
+
"sourcesContent": ["import { Awaitable } from '@tldraw/utils'\nimport { ComponentType, Fragment } from 'react'\nimport { DEFAULT_CAMERA_OPTIONS } from './constants'\nimport type { Editor } from './editor/Editor'\nimport { TLContent } from './editor/types/clipboard-types'\nimport { TLExternalContent } from './editor/types/external-content'\nimport { TLCameraOptions } from './editor/types/misc-types'\nimport { VecLike } from './primitives/Vec'\nimport { TLDeepLinkOptions } from './utils/deepLinks'\nimport { TLTextOptions } from './utils/richText'\n\n/**\n * Identifies how a clipboard write was triggered (copy vs cut, keyboard vs menu).\n *\n * @public\n */\nexport interface TLClipboardWriteInfo {\n\treadonly operation: 'copy' | 'cut'\n\treadonly source: 'native' | 'menu'\n}\n\n/**\n * Raw clipboard paste payload, before tldraw parses clipboard contents into {@link TLExternalContent}.\n *\n * - `native-event`: from the `paste` event \u2014 `clipboardData` is available synchronously (unlike async\n * `navigator.clipboard.read()`).\n * - `clipboard-read`: from an explicit `navigator.clipboard.read()` call \u2014 only `ClipboardItem[]`\n * exists\n * (no `DataTransfer`).\n *\n * @public\n */\nexport type TLClipboardPasteRawInfo =\n\t| {\n\t\t\treadonly editor: Editor\n\t\t\treadonly source: 'native-event'\n\t\t\treadonly event: ClipboardEvent\n\t\t\treadonly clipboardData: DataTransfer | null\n\t\t\treadonly point: VecLike | undefined\n\t }\n\t| {\n\t\t\treadonly editor: Editor\n\t\t\treadonly source: 'clipboard-read'\n\t\t\treadonly clipboardItems: readonly ClipboardItem[]\n\t\t\treadonly point: VecLike | undefined\n\t }\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly uiDragDistanceSquared: number\n\treadonly uiCoarseDragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\t/**\n\t * How long (in milliseconds) to fade all laser scribbles after the session ends.\n\t * The total points across all scribbles will be removed proportionally over this duration.\n\t * Defaults to 500ms (0.5 seconds).\n\t */\n\treadonly laserFadeoutMs: number\n\treadonly maxExportDelayMs: number\n\treadonly tooltipDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.\n\t */\n\treadonly enableToolbarKeyboardShortcuts: boolean\n\t/**\n\t * The maximum number of fonts that will be loaded while blocking the main rendering of the\n\t * canvas. If there are more than this number of fonts needed, we'll just show the canvas right\n\t * away and let the fonts load in in the background.\n\t */\n\treadonly maxFontsToLoadBeforeRender: number\n\t/**\n\t * If you have a CSP policy that blocks inline styles, you can use this prop to provide a\n\t * nonce to use in the editor's styles.\n\t */\n\treadonly nonce: string | undefined\n\t/**\n\t * Branding name of the app, currently only used for adding aria-label for the application.\n\t */\n\treadonly branding?: string\n\t/**\n\t * Whether to use debounced zoom level for certain rendering optimizations. When true,\n\t * `editor.getEfficientZoomLevel()` returns a cached zoom value while the camera is moving,\n\t * reducing re-renders. When false, it always returns the current zoom level.\n\t */\n\treadonly debouncedZoom: boolean\n\t/**\n\t * The number of shapes that must be on the page for the debounced zoom level to be used.\n\t * Defaults to 500 shapes.\n\t */\n\treadonly debouncedZoomThreshold: number\n\t/**\n\t * Whether to allow spacebar panning. When true, the spacebar will pan the camera when held down.\n\t * When false, the spacebar will not pan the camera.\n\t */\n\treadonly spacebarPanning: boolean\n\t/**\n\t * Whether to allow right-click + drag to pan the camera. When true, right-click + drag pans the\n\t * camera and a static right-click opens the context menu at the release position. When false,\n\t * right-click opens the context menu on press (no drag-to-pan).\n\t */\n\treadonly rightClickPanning: boolean\n\t/**\n\t * The default padding (in pixels) used when zooming to fit content in the viewport.\n\t * This affects methods like `zoomToFit()`, `zoomToSelection()`, and `zoomToBounds()`.\n\t * The actual padding used is the minimum of this value and 28% of the viewport width.\n\t * Defaults to 128 pixels.\n\t */\n\treadonly zoomToFitPadding: number\n\t/**\n\t * The distance (in screen pixels) at which shapes snap to guides and other shapes.\n\t */\n\treadonly snapThreshold: number\n\t/**\n\t * Options for the editor's camera. These are the initial camera options.\n\t * Use {@link Editor.setCameraOptions} to update camera options at runtime.\n\t */\n\treadonly camera: Partial<TLCameraOptions>\n\t/**\n\t * Options for the editor's text rendering. These include TipTap configuration and\n\t * font handling. These are the initial text options and cannot be changed at runtime.\n\t */\n\treadonly text: TLTextOptions\n\t/**\n\t * Options for syncing the editor's camera state with the URL. Set to `true` to enable\n\t * with default options, or pass an options object to customize behavior.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Enable with defaults\n\t * <Tldraw options={{ deepLinks: true }} />\n\t *\n\t * // Enable with custom options\n\t * <Tldraw options={{ deepLinks: { param: 'd', debounceMs: 500 } }} />\n\t * ```\n\t */\n\treadonly deepLinks: true | TLDeepLinkOptions | undefined\n\t/**\n\t * Whether the quick-zoom brush preserves its screen-pixel size when the user\n\t * zooms the overview. When true, zooming in shrinks the target viewport (higher\n\t * return zoom); zooming out expands it. When false, the brush keeps the original\n\t * viewport's page dimensions regardless of overview zoom changes.\n\t */\n\treadonly quickZoomPreservesScreenBounds: boolean\n\t/**\n\t * Called before content is written to the clipboard during a copy or cut operation.\n\t * Receives the serialized content (shapes, bindings, assets) and can filter or transform\n\t * it before it reaches the clipboard.\n\t *\n\t * Return a modified `TLContent` object to change what is copied or cut. Return `false` to\n\t * cancel the clipboard write (for cut, the selected shapes are not removed). Return `void`\n\t * (or `undefined`) to pass through unchanged. You may return a `Promise` of those values if\n\t * the hook is async.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Filter out \"locked\" shapes from copy\n\t * onBeforeCopyToClipboard({ content, operation }) {\n\t * return {\n\t * ...content,\n\t * shapes: content.shapes.filter(s => !s.meta.locked),\n\t * rootShapeIds: content.rootShapeIds.filter(id =>\n\t * content.shapes.find(s => s.id === id && !s.meta.locked)\n\t * ),\n\t * }\n\t * }\n\t * ```\n\t */\n\tonBeforeCopyToClipboard?(\n\t\tinfo: { editor: Editor; content: TLContent } & TLClipboardWriteInfo\n\t): Awaitable<TLContent | false | void>\n\t/**\n\t * Called before pasted content is processed and shapes are created. Receives the parsed\n\t * external content from the clipboard and can filter, transform, or cancel it.\n\t *\n\t * Return `false` to cancel the paste. Return a modified content object to transform it.\n\t * Return `void` (or `undefined`) to pass through unchanged. You may return a `Promise` of\n\t * those values if the hook is async.\n\t *\n\t * This only fires for clipboard paste operations (keyboard shortcuts and menu actions),\n\t * not for file drops or programmatic `putExternalContent` calls.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Block pasting of image files\n\t * onBeforePasteFromClipboard({ content }) {\n\t * if (content.type === 'files') {\n\t * const nonImages = content.files.filter(f => !f.type.startsWith('image/'))\n\t * if (nonImages.length === 0) return false\n\t * return { ...content, files: nonImages }\n\t * }\n\t * }\n\t * ```\n\t */\n\tonBeforePasteFromClipboard?(info: {\n\t\teditor: Editor\n\t\tcontent: TLExternalContent<unknown>\n\t\tsource: 'native-event' | 'clipboard-read'\n\t\tpoint?: VecLike\n\t}): Awaitable<TLExternalContent<unknown> | false | void>\n\t/**\n\t * Called first for keyboard and menu paste, **before** tldraw handles or parses clipboard data\n\t * (and before {@link TldrawOptions.onBeforePasteFromClipboard}).\n\t *\n\t * Return `false` to cancel tldraw's default paste handling for this gesture (same convention as\n\t * {@link TldrawOptions.onBeforePasteFromClipboard}). Use this when you handle paste yourself from\n\t * raw clipboard data, or to block the gesture entirely. Return `void` (or `undefined`) to continue.\n\t */\n\tonClipboardPasteRaw?(info: TLClipboardPasteRawInfo): false | void\n\t/**\n\t * Called when content is dropped on the canvas. Provides the page position\n\t * where the drop occurred and the underlying drag event object.\n\t * Return true to prevent default drop handling (files, URLs, etc.)\n\t */\n\texperimental__onDropOnCanvas?(options: {\n\t\tpoint: VecLike\n\t\tevent: React.DragEvent<Element>\n\t}): boolean\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tuiDragDistanceSquared: 16, // 4 squared\n\t// it's really easy to accidentally drag from the toolbar on mobile, so we use a much larger\n\t// threshold than usual here to try and prevent accidental drags.\n\tuiCoarseDragDistanceSquared: 625, // 25 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tlaserFadeoutMs: 500,\n\tmaxExportDelayMs: 5000,\n\ttooltipDelayMs: 700,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n\tactionShortcutsLocation: 'swap',\n\tcreateTextOnCanvasDoubleClick: true,\n\texportProvider: Fragment,\n\tenableToolbarKeyboardShortcuts: true,\n\tmaxFontsToLoadBeforeRender: Infinity,\n\tnonce: undefined,\n\tdebouncedZoom: true,\n\tdebouncedZoomThreshold: 500,\n\tspacebarPanning: true,\n\trightClickPanning: true,\n\tzoomToFitPadding: 128,\n\tsnapThreshold: 8,\n\tcamera: DEFAULT_CAMERA_OPTIONS,\n\ttext: {},\n\tdeepLinks: undefined,\n\tquickZoomPreservesScreenBounds: true,\n\tonBeforeCopyToClipboard: undefined,\n\tonBeforePasteFromClipboard: undefined,\n\tonClipboardPasteRaw: undefined,\n\texperimental__onDropOnCanvas: undefined,\n} as const satisfies TldrawOptions\n"],
|
|
5
|
+
"mappings": "AACA,SAAwB,gBAAgB;AACxC,SAAS,8BAA8B;AAuRhC,MAAM,uBAAuB;AAAA,EACnC,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA;AAAA,EAC3B,qBAAqB;AAAA;AAAA,EACrB,uBAAuB;AAAA;AAAA;AAAA;AAAA,EAGvB,6BAA6B;AAAA;AAAA,EAC7B,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,WAAW;AAAA,IACV,EAAE,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG;AAAA,IAC/B,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG;AAAA,IAClC,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,IAC7B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,gBAAgB;AAAA,EAChB,gCAAgC;AAAA,EAChC,4BAA4B;AAAA,EAC5B,OAAO;AAAA,EACP,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,MAAM,CAAC;AAAA,EACP,WAAW;AAAA,EACX,gCAAgC;AAAA,EAChC,yBAAyB;AAAA,EACzB,4BAA4B;AAAA,EAC5B,qBAAqB;AAAA,EACrB,8BAA8B;AAC/B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -19,10 +19,16 @@ function kickoutOccludedShapes(editor, shapeIds, opts) {
|
|
|
19
19
|
} else {
|
|
20
20
|
const overlappingChildren = getOverlappingShapes(editor, parent.id, childIds);
|
|
21
21
|
if (overlappingChildren.length < childIds.length) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const parentUtil = editor.getShapeUtil(parent);
|
|
23
|
+
const lostChildIds = childIds.filter((id) => {
|
|
24
|
+
if (overlappingChildren.includes(id)) return false;
|
|
25
|
+
const child = editor.getShape(id);
|
|
26
|
+
if (!child) return false;
|
|
27
|
+
return parentUtil.canRemoveChildrenOfType(parent, child.type);
|
|
28
|
+
});
|
|
29
|
+
if (lostChildIds.length > 0) {
|
|
30
|
+
parentsToLostChildren.set(parent, lostChildIds);
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
34
|
}
|
|
@@ -126,9 +132,16 @@ function getDroppedShapesToNewParents(editor, shapes, cb) {
|
|
|
126
132
|
const shapeGroupIds = /* @__PURE__ */ new Map();
|
|
127
133
|
const reparenting = /* @__PURE__ */ new Map();
|
|
128
134
|
const remainingShapesToReparent = new Set(shapesToActuallyCheck);
|
|
129
|
-
const potentialParentShapes = editor.getCurrentPageShapesSorted().filter(
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
const potentialParentShapes = editor.getCurrentPageShapesSorted().filter((parentShape) => {
|
|
136
|
+
if (remainingShapesToReparent.has(parentShape)) return false;
|
|
137
|
+
const parentUtil = editor.getShapeUtil(parentShape);
|
|
138
|
+
for (const childShape of remainingShapesToReparent) {
|
|
139
|
+
if (parentUtil.canReceiveNewChildrenOfType(parentShape, childShape.type)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
});
|
|
132
145
|
parentCheck: for (let i = potentialParentShapes.length - 1; i >= 0; i--) {
|
|
133
146
|
const parentShape = potentialParentShapes[i];
|
|
134
147
|
const parentShapeContainingGroupId = editor.findShapeAncestor(
|