diff --git a/src/main/frontend/extensions/tldraw.cljs b/src/main/frontend/extensions/tldraw.cljs index 2df81d913e6..ec96b41c301 100644 --- a/src/main/frontend/extensions/tldraw.cljs +++ b/src/main/frontend/extensions/tldraw.cljs @@ -153,7 +153,7 @@ (tldraw {:renderers tldraw-renderers :handlers (get-tldraw-handlers page-name) :onMount on-mount - :isPublishing config/publishing? + :readOnly config/publishing? :onPersist (fn [app info] (state/set-state! [:whiteboard/last-persisted-at (state/get-current-repo)] (util/time-ms)) (util/profile "tldraw persist" diff --git a/tldraw/apps/tldraw-logseq/src/app.tsx b/tldraw/apps/tldraw-logseq/src/app.tsx index 788c48c8653..ce0a78b215e 100644 --- a/tldraw/apps/tldraw-logseq/src/app.tsx +++ b/tldraw/apps/tldraw-logseq/src/app.tsx @@ -53,7 +53,7 @@ const tools: TLReactToolConstructor[] = [ interface LogseqTldrawProps { renderers: LogseqContextValue['renderers'] handlers: LogseqContextValue['handlers'] - isPublishing: LogseqContextValue['isPublishing'] + readOnly: boolean model?: TLDocumentModel onMount?: TLReactCallbacks['onMount'] onPersist?: TLReactCallbacks['onPersist'] @@ -92,13 +92,14 @@ const AppImpl = () => { const AppInner = ({ onPersist, + readOnly, model, ...rest }: Omit) => { const onDrop = useDrop() const onPaste = usePaste() const onCopy = useCopy() - const onQuickAdd = useQuickAdd() + const onQuickAdd = readOnly ? null : useQuickAdd() const onPersistOnDiff: TLReactCallbacks['onPersist'] = React.useCallback( (app, info) => { @@ -114,6 +115,7 @@ const AppInner = ({ onDrop={onDrop} onPaste={onPaste} onCopy={onCopy} + readOnly={readOnly} onCanvasDBClick={onQuickAdd} onPersist={onPersistOnDiff} model={model} @@ -124,7 +126,7 @@ const AppInner = ({ ) } -export const App = function App({ renderers, handlers, isPublishing, ...rest }: LogseqTldrawProps): JSX.Element { +export const App = function App({ renderers, handlers, ...rest }: LogseqTldrawProps): JSX.Element { const memoRenders: any = React.useMemo(() => { return Object.fromEntries( Object.entries(renderers).map(([key, comp]) => { @@ -136,7 +138,6 @@ export const App = function App({ renderers, handlers, isPublishing, ...rest }: const contextValue = { renderers: memoRenders, handlers: handlers, - isPublishing: isPublishing, } return ( diff --git a/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx b/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx index 9d3496e8bf0..ff48e505757 100644 --- a/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx +++ b/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx @@ -8,11 +8,9 @@ import { TablerIcon } from '../icons' import { Button } from '../Button' import { ZoomMenu } from '../ZoomMenu' import * as Separator from '@radix-ui/react-separator' -import { LogseqContext } from './../../lib/logseq-context' export const ActionBar = observer(function ActionBar(): JSX.Element { const app = useApp() - const { isPublishing } = React.useContext(LogseqContext) const undo = React.useCallback(() => { app.api.undo() @@ -32,7 +30,7 @@ export const ActionBar = observer(function ActionBar(): JSX.Element { return (
- {!isPublishing && ( + {!app.readOnly && (
)} -
+
diff --git a/tldraw/apps/tldraw-logseq/src/components/AppUI.tsx b/tldraw/apps/tldraw-logseq/src/components/AppUI.tsx index 94eabe2dbdf..d69bffb2d75 100644 --- a/tldraw/apps/tldraw-logseq/src/components/AppUI.tsx +++ b/tldraw/apps/tldraw-logseq/src/components/AppUI.tsx @@ -4,18 +4,16 @@ import { DevTools } from './Devtools' import { PrimaryTools } from './PrimaryTools' import { StatusBar } from './StatusBar' import { isDev } from '@tldraw/core' -import { LogseqContext } from './../lib/logseq-context' -import React from 'react' - +import { useApp } from '@tldraw/react' export const AppUI = observer(function AppUI() { - const { isPublishing } = React.useContext(LogseqContext) + const app = useApp() return ( <> {isDev() && } {isDev() && } - {!isPublishing && } + {!app.readOnly && } ) diff --git a/tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx b/tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx index 513d76a81da..0adce381f6a 100644 --- a/tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx +++ b/tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx @@ -566,9 +566,6 @@ const getContextBarActionTypes = (type: ShapeType) => { } export const getContextBarActionsForShapes = (shapes: Shape[]) => { - const {isPublishing} = React.useContext(LogseqContext) - if (isPublishing) return [] - const types = shapes.map(s => s.props.type) const actionTypes = new Set(shapes.length > 0 ? getContextBarActionTypes(types[0]) : []) for (let i = 1; i < types.length && actionTypes.size > 0; i++) { diff --git a/tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx b/tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx index a1cbb0679f3..4e0f0d74850 100644 --- a/tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx +++ b/tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx @@ -4,7 +4,6 @@ import { observer } from 'mobx-react-lite' import { TablerIcon } from '../icons' import { Button } from '../Button' import * as React from 'react' -import { LogseqContext } from './../../lib/logseq-context' import * as ReactContextMenu from '@radix-ui/react-context-menu' import * as Separator from '@radix-ui/react-separator' @@ -21,7 +20,6 @@ export const ContextMenu = observer(function ContextMenu({ }: ContextMenuProps) { const app = useApp() const rContent = React.useRef(null) - const { isPublishing } = React.useContext(LogseqContext) const runAndTransition = (f: Function) => { f() @@ -56,7 +54,7 @@ export const ContextMenu = observer(function ContextMenu({ tabIndex={-1} >
- {app.selectedShapes?.size > 1 && !isPublishing && ( + {app.selectedShapes?.size > 1 && !app.readOnly && ( <>
@@ -145,7 +143,7 @@ export const ContextMenu = observer(function ContextMenu({ )} {(app.selectedShapesArray.some(s => s.type === 'group' || app.getParentGroup(s)) || app.selectedShapesArray.length > 1) && - !isPublishing && ( + !app.readOnly && ( <> {app.selectedShapesArray.some(s => s.type === 'group' || app.getParentGroup(s)) && ( 0 && ( <> - {!isPublishing && ( + {!app.readOnly && ( runAndTransition(app.cut)} @@ -208,7 +206,7 @@ export const ContextMenu = observer(function ContextMenu({ )} - {!isPublishing && ( + {!app.readOnly && ( runAndTransition(app.paste)} @@ -222,7 +220,7 @@ export const ContextMenu = observer(function ContextMenu({
)} - {app.selectedShapes?.size === 1 && !isPublishing && ( + {app.selectedShapes?.size === 1 && !app.readOnly && ( runAndTransition(() => app.paste(undefined, true))} @@ -255,7 +253,7 @@ export const ContextMenu = observer(function ContextMenu({ Deselect all )} - {app.selectedShapes?.size > 0 && !isPublishing && ( + {app.selectedShapes?.size > 0 && !app.readOnly && ( <>
- {app.selectedShapes?.size > 1 && !isPublishing && ( + {app.selectedShapes?.size > 1 && !app.readOnly && ( <> )} - {!isPublishing && ( + {!app.readOnly && ( <> void copyToClipboard: (text: string, html: string) => void } - isPublishing: boolean } export const LogseqContext = React.createContext({} as LogseqContextValue) diff --git a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx index d70247ac2d9..7a55072ed81 100644 --- a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx +++ b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx @@ -508,13 +508,15 @@ export class LogseqPortalShape extends TLBoxShape { {targetNotFound &&
Target not found
} {showingPortal && }
- + {!app.readOnly && ( + + )} )}
diff --git a/tldraw/packages/core/src/lib/TLApi/TLApi.ts b/tldraw/packages/core/src/lib/TLApi/TLApi.ts index 9c816483384..4d24eaa96a3 100644 --- a/tldraw/packages/core/src/lib/TLApi/TLApi.ts +++ b/tldraw/packages/core/src/lib/TLApi/TLApi.ts @@ -367,6 +367,8 @@ export class TLApi { + if (this.app.readOnly) return + const selectedGroups: S[] = [ ...shapes.filter(s => s.type === 'group'), ...shapes.map(s => this.app.getParentGroup(s)), @@ -393,6 +395,8 @@ export class TLApi { + if (this.app.readOnly) return + const selectedGroups: S[] = [ ...shapes.filter(s => s.type === 'group'), ...shapes.map(s => this.app.getParentGroup(s)), diff --git a/tldraw/packages/core/src/lib/TLApp/TLApp.ts b/tldraw/packages/core/src/lib/TLApp/TLApp.ts index 958aa8452b3..929501796ea 100644 --- a/tldraw/packages/core/src/lib/TLApp/TLApp.ts +++ b/tldraw/packages/core/src/lib/TLApp/TLApp.ts @@ -52,10 +52,12 @@ export class TLApp< constructor( serializedApp?: TLDocumentModel, Shapes?: TLShapeConstructor[], - Tools?: TLToolConstructor[] + Tools?: TLToolConstructor[], + readOnly?: boolean ) { super() this._states = [TLSelectTool, TLMoveTool] + this.readOnly = readOnly this.history.pause() if (this.states && this.states.length > 0) { this.registerStates(this.states) @@ -78,6 +80,8 @@ export class TLApp< keybindingRegistered = false uuid = uniqueId() + readOnly: boolean | undefined + static id = 'app' static initial = 'select' @@ -205,7 +209,7 @@ export class TLApp< // @ts-expect-error ??? keys: child.constructor['shortcut'] as string | string[], fn: (_: any, __: any, e: KeyboardEvent) => { - this.transition(child.id) + this.selectTool(child.id) // hack: allows logseq related shortcut combinations to work // fixme?: unsure if it will cause unexpected issues // e.stopPropagation() @@ -323,6 +327,8 @@ export class TLApp< } @action readonly createShapes = (shapes: S[] | TLShapeModel[]): this => { + if (this.readOnly) return this + const newShapes = this.currentPage.addShapes(...shapes) if (newShapes) this.notify('create-shapes', newShapes) this.persist() @@ -330,13 +336,15 @@ export class TLApp< } @action updateShapes = (shapes: ({ id: string } & Partial)[]): this => { + if (this.readOnly) return this + shapes.forEach(shape => this.getShapeById(shape.id)?.update(shape)) this.persist() return this } @action readonly deleteShapes = (shapes: S[] | string[]): this => { - if (shapes.length === 0) return this + if (shapes.length === 0 || this.readOnly) return this const normalizedShapes: S[] = shapes .map(shape => (typeof shape === 'string' ? this.getShapeById(shape) : shape)) .filter(isNonNullable) @@ -408,22 +416,22 @@ export class TLApp< } bringForward = (shapes: S[] | string[] = this.selectedShapesArray): this => { - if (shapes.length > 0) this.currentPage.bringForward(shapes) + if (shapes.length > 0 && !this.readOnly) this.currentPage.bringForward(shapes) return this } sendBackward = (shapes: S[] | string[] = this.selectedShapesArray): this => { - if (shapes.length > 0) this.currentPage.sendBackward(shapes) + if (shapes.length > 0 && !this.readOnly) this.currentPage.sendBackward(shapes) return this } sendToBack = (shapes: S[] | string[] = this.selectedShapesArray): this => { - if (shapes.length > 0) this.currentPage.sendToBack(shapes) + if (shapes.length > 0 && !this.readOnly) this.currentPage.sendToBack(shapes) return this } bringToFront = (shapes: S[] | string[] = this.selectedShapesArray): this => { - if (shapes.length > 0) this.currentPage.bringToFront(shapes) + if (shapes.length > 0 && !this.readOnly) this.currentPage.bringToFront(shapes) return this } @@ -438,7 +446,7 @@ export class TLApp< } align = (type: AlignType, shapes: S[] = this.selectedShapesArray): this => { - if (shapes.length < 2) return this + if (shapes.length < 2 || this.readOnly) return this const boundsForShapes = shapes.map(shape => { const bounds = shape.getBounds() @@ -482,7 +490,7 @@ export class TLApp< } distribute = (type: DistributeType, shapes: S[] = this.selectedShapesArray): this => { - if (shapes.length < 2) return this + if (shapes.length < 2 || this.readOnly) return this const deltaMap = Object.fromEntries( BoundsUtils.getDistributions(shapes, type).map(d => [d.id, d]) @@ -497,7 +505,7 @@ export class TLApp< } packIntoRectangle = (shapes: S[] = this.selectedShapesArray): this => { - if (shapes.length < 2) return this + if (shapes.length < 2 || this.readOnly) return this const deltaMap = Object.fromEntries( BoundsUtils.getPackedDistributions(shapes).map(d => [d.id, d]) @@ -585,7 +593,7 @@ export class TLApp< } paste = (e?: ClipboardEvent, shiftKey?: boolean) => { - if (!this.editingShape) { + if (!this.editingShape && !this.readOnly) { this.notify('paste', { point: this.inputs.currentPoint, shiftKey: !!shiftKey, @@ -616,7 +624,10 @@ export class TLApp< return this.currentState } - selectTool = this.transition + selectTool = (id: string, data: AnyObject = {}) => { + if (!this.readOnly || ['select', 'move'].includes(id) ) + this.transition(id, data) + } registerTools(tools: TLToolConstructor[]) { this.Tools = tools @@ -918,6 +929,7 @@ export class TLApp< this.isInAny('select.idle', 'select.hoveringSelectionHandle') && !this.isIn('select.contextMenu') && selectedShapesArray.length > 0 && + !this.readOnly && !selectedShapesArray.every(shape => shape.hideContextBar) ) } @@ -932,6 +944,7 @@ export class TLApp< 'select.pointingResizeHandle' ) && selectedShapesArray.length > 0 && + !this.readOnly && !selectedShapesArray.some(shape => shape.hideRotateHandle) ) } @@ -948,6 +961,7 @@ export class TLApp< 'select.pointingResizeHandle' ) && selectedShapesArray.length === 1 && + !this.readOnly && !selectedShapesArray.every(shape => shape.hideResizeHandles) ) } diff --git a/tldraw/packages/core/src/lib/tools/TLBoxTool/states/PointingState.tsx b/tldraw/packages/core/src/lib/tools/TLBoxTool/states/PointingState.tsx index d0d04613726..27d85764cbd 100644 --- a/tldraw/packages/core/src/lib/tools/TLBoxTool/states/PointingState.tsx +++ b/tldraw/packages/core/src/lib/tools/TLBoxTool/states/PointingState.tsx @@ -16,7 +16,7 @@ export class PointingState< onPointerMove: TLStateEvents['onPointerMove'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('creating') this.app.setSelectedShapes(this.app.currentPage.shapes) } diff --git a/tldraw/packages/core/src/lib/tools/TLDotTool/states/IdleState.tsx b/tldraw/packages/core/src/lib/tools/TLDotTool/states/IdleState.tsx index edfefce94ba..49423b5690e 100644 --- a/tldraw/packages/core/src/lib/tools/TLDotTool/states/IdleState.tsx +++ b/tldraw/packages/core/src/lib/tools/TLDotTool/states/IdleState.tsx @@ -14,7 +14,7 @@ export class IdleState< static id = 'idle' onPointerDown: TLStateEvents['onPointerDown'] = (info, e) => { - if (info.order) return + if (info.order || this.app.readOnly) return this.tool.transition('creating') } diff --git a/tldraw/packages/core/src/lib/tools/TLDrawTool/states/IdleState.tsx b/tldraw/packages/core/src/lib/tools/TLDrawTool/states/IdleState.tsx index 3e724e30172..4dcd58802b4 100644 --- a/tldraw/packages/core/src/lib/tools/TLDrawTool/states/IdleState.tsx +++ b/tldraw/packages/core/src/lib/tools/TLDrawTool/states/IdleState.tsx @@ -14,7 +14,7 @@ export class IdleState< static id = 'idle' onPointerDown: TLStateEvents['onPointerDown'] = (info, e) => { - if (info.order) return + if (info.order || this.app.readOnly) return this.tool.transition('creating') } diff --git a/tldraw/packages/core/src/lib/tools/TLLineTool/states/PointingState.tsx b/tldraw/packages/core/src/lib/tools/TLLineTool/states/PointingState.tsx index b06c5dc36db..b6dca2466b5 100644 --- a/tldraw/packages/core/src/lib/tools/TLLineTool/states/PointingState.tsx +++ b/tldraw/packages/core/src/lib/tools/TLLineTool/states/PointingState.tsx @@ -16,7 +16,7 @@ export class PointingState< onPointerMove: TLStateEvents['onPointerMove'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('creating') this.app.setSelectedShapes(this.app.currentPage.shapes) } diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/HoveringSelectionHandleState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/HoveringSelectionHandleState.ts index 32bdd519cb0..f93b100523b 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/HoveringSelectionHandleState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/HoveringSelectionHandleState.ts @@ -69,7 +69,7 @@ export class HoveringSelectionHandleState< } onDoubleClick: TLEvents['pointer'] = info => { - if (info.order) return + if (info.order || this.app.readOnly) return const isSingle = this.app.selectedShapes.size === 1 if (!isSingle) return const selectedShape = getFirstFromSet(this.app.selectedShapes) diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/IdleState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/IdleState.ts index b538c0f65c9..da4624d320c 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/IdleState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/IdleState.ts @@ -121,9 +121,8 @@ export class IdleState< } onDoubleClick: TLEvents['pointer'] = info => { - if (info.order) return + if (info.order || this.app.selectedShapesArray.length !== 1 || this.app.readOnly) return - if (this.app.selectedShapesArray.length !== 1) return const selectedShape = this.app.selectedShapesArray[0] if (!selectedShape.canEdit) return @@ -148,7 +147,7 @@ export class IdleState< const { selectedShapesArray } = this.app switch (e.key) { case 'Enter': { - if (selectedShapesArray.length === 1 && selectedShapesArray[0].canEdit) { + if (selectedShapesArray.length === 1 && selectedShapesArray[0].canEdit && !this.app.readOnly) { this.tool.transition('editingShape', { type: TLTargetType.Shape, shape: selectedShapesArray[0], diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingBoundsBackgroundState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingBoundsBackgroundState.ts index cc0b2aafd10..739709dc42e 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingBoundsBackgroundState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingBoundsBackgroundState.ts @@ -17,7 +17,7 @@ export class PointingBoundsBackgroundState< onPointerMove: TLEvents['pointer'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('translating') } } diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingSelectedShapeState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingSelectedShapeState.ts index 65866c9d299..80b379c00f8 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingSelectedShapeState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingSelectedShapeState.ts @@ -31,7 +31,7 @@ export class PointingSelectedShapeState< onPointerMove: TLEvents['pointer'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('translating') } } @@ -48,6 +48,7 @@ export class PointingSelectedShapeState< } else if ( selectedShapesArray.length === 1 && this.pointedSelectedShape.canEdit && + !this.app.readOnly && this.pointedSelectedShape instanceof TLBoxShape && PointUtils.pointInBounds(currentPoint, this.pointedSelectedShape.bounds) ) { diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeBehindBoundsState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeBehindBoundsState.ts index 8a87ad378d3..e2b6914f2a9 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeBehindBoundsState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeBehindBoundsState.ts @@ -21,7 +21,7 @@ export class PointingShapeBehindBoundsState< onPointerMove: TLEvents['pointer'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('translating') } } diff --git a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeState.ts b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeState.ts index 362f9542c8e..6dd4781a54e 100644 --- a/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeState.ts +++ b/tldraw/packages/core/src/lib/tools/TLSelectTool/states/PointingShapeState.ts @@ -28,7 +28,7 @@ export class PointingShapeState< onPointerMove: TLEvents['pointer'] = () => { const { currentPoint, originPoint } = this.app.inputs - if (Vec.dist(currentPoint, originPoint) > 5) { + if (Vec.dist(currentPoint, originPoint) > 5 && !this.app.readOnly) { this.tool.transition('translating') } } diff --git a/tldraw/packages/core/src/lib/tools/TLTextTool/states/IdleState.tsx b/tldraw/packages/core/src/lib/tools/TLTextTool/states/IdleState.tsx index 6e603aaf53a..fdf9a0dd07b 100644 --- a/tldraw/packages/core/src/lib/tools/TLTextTool/states/IdleState.tsx +++ b/tldraw/packages/core/src/lib/tools/TLTextTool/states/IdleState.tsx @@ -14,7 +14,7 @@ export class IdleState< static id = 'idle' onPointerDown: TLStateEvents['onPointerDown'] = (info, e) => { - if (info.order) return + if (info.order || this.app.readOnly) return this.tool.transition('creating') } diff --git a/tldraw/packages/react/src/components/App.tsx b/tldraw/packages/react/src/components/App.tsx index 3f907221bca..46fcdd47e43 100644 --- a/tldraw/packages/react/src/components/App.tsx +++ b/tldraw/packages/react/src/components/App.tsx @@ -26,6 +26,7 @@ export interface TLAppPropsWithoutApp< Shapes?: TLReactShapeConstructor[] Tools?: TLToolConstructor>[] children?: React.ReactNode + readOnly?: boolean } export interface TLAppPropsWithApp< diff --git a/tldraw/packages/react/src/hooks/useAppSetup.ts b/tldraw/packages/react/src/hooks/useAppSetup.ts index 546291d90bb..627ab29c839 100644 --- a/tldraw/packages/react/src/hooks/useAppSetup.ts +++ b/tldraw/packages/react/src/hooks/useAppSetup.ts @@ -6,7 +6,7 @@ export function useAppSetup = TL props: TLAppPropsWithoutApp | TLAppPropsWithApp ): R { if ('app' in props) return props.app - const [app] = React.useState(() => new TLReactApp(props.model, props.Shapes, props.Tools) as R) + const [app] = React.useState(() => new TLReactApp(props.model, props.Shapes, props.Tools, props.readOnly) as R) React.useLayoutEffect(() => { app.initKeyboardShortcuts()