diff --git a/src/main/frontend/components/container.css b/src/main/frontend/components/container.css index ccce10ffbcb..09b5c2c90cd 100644 --- a/src/main/frontend/components/container.css +++ b/src/main/frontend/components/container.css @@ -524,7 +524,7 @@ html[data-theme='dark'] { } &-btn { - @apply fixed bottom-4 right-8; + @apply fixed bottom-4 right-4 sm:right-8; > .inner { @apply font-bold diff --git a/src/main/frontend/components/whiteboard.css b/src/main/frontend/components/whiteboard.css index e6f6184ab36..51427384b4f 100644 --- a/src/main/frontend/components/whiteboard.css +++ b/src/main/frontend/components/whiteboard.css @@ -205,7 +205,7 @@ input.tl-text-input { .tl-action-bar { left: 0.5rem; - bottom: 0.5rem; + bottom: 0; } .tl-primary-tools { diff --git a/src/resources/dicts/en.edn b/src/resources/dicts/en.edn index 9a6eacf75e6..42d7421c198 100644 --- a/src/resources/dicts/en.edn +++ b/src/resources/dicts/en.edn @@ -465,6 +465,7 @@ :whiteboard/dashboard-card-edited "Edited " :whiteboard/toggle-grid "Toggle grid" :whiteboard/snap-to-grid "Snap to grid" + :whiteboard/toggle-pen-mode "Toggle pen mode" :flashcards/modal-welcome-title "Time to create a card!" :flashcards/modal-welcome-desc-1 "You can add \"#card\" to any block to turn it into a card or trigger \"/cloze\" to add some clozes." :flashcards/modal-welcome-desc-2 "You can " diff --git a/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx b/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx index 430783b6a08..4183dc50e0a 100644 --- a/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx +++ b/tldraw/apps/tldraw-logseq/src/components/ActionBar/ActionBar.tsx @@ -41,10 +41,14 @@ export const ActionBar = observer(function ActionBar(): JSX.Element { app.api.toggleSnapToGrid() }, [app]) + const togglePenMode = React.useCallback(() => { + app.api.togglePenMode() + }, [app]) + return (
{!app.readOnly && ( -
+
@@ -54,7 +58,7 @@ export const ActionBar = observer(function ActionBar(): JSX.Element {
)} -
+
@@ -65,7 +69,7 @@ export const ActionBar = observer(function ActionBar(): JSX.Element {
-
+
)}
+ + {!app.readOnly && ( +
+ + + +
+ )}
) }) diff --git a/tldraw/apps/tldraw-logseq/src/styles.css b/tldraw/apps/tldraw-logseq/src/styles.css index 61553f6f47d..0f91cc68a49 100644 --- a/tldraw/apps/tldraw-logseq/src/styles.css +++ b/tldraw/apps/tldraw-logseq/src/styles.css @@ -166,7 +166,7 @@ html[data-theme='light'] { } .tl-action-bar { - @apply absolute bottom-0 flex items-center border-0 left-10 bottom-10; + @apply absolute flex items-center border-0 left-10 bottom-8 flex-wrap-reverse pr-12; z-index: 100000; user-select: none; diff --git a/tldraw/packages/core/src/lib/TLApi/TLApi.ts b/tldraw/packages/core/src/lib/TLApi/TLApi.ts index 3b6989fb05c..ab8bd2e4f9a 100644 --- a/tldraw/packages/core/src/lib/TLApi/TLApi.ts +++ b/tldraw/packages/core/src/lib/TLApi/TLApi.ts @@ -178,6 +178,13 @@ export class TLApi { + const { settings } = this.app + settings.update({ penMode: !settings.penMode }) + return this + } + setColor = (color: string): this => { const { settings } = this.app diff --git a/tldraw/packages/core/src/lib/TLSettings.ts b/tldraw/packages/core/src/lib/TLSettings.ts index c6383ef6f8f..2757a4d5a15 100644 --- a/tldraw/packages/core/src/lib/TLSettings.ts +++ b/tldraw/packages/core/src/lib/TLSettings.ts @@ -4,6 +4,7 @@ import { observable, makeObservable, action } from 'mobx' export interface TLSettingsProps { mode: 'light' | 'dark' showGrid: boolean + penMode: boolean snapToGrid: boolean color: string scaleLevel: string @@ -17,6 +18,7 @@ export class TLSettings implements TLSettingsProps { @observable mode: 'dark' | 'light' = 'light' @observable showGrid = true @observable snapToGrid = true + @observable penMode = false @observable scaleLevel = 'md' @observable color = '' diff --git a/tldraw/packages/react/src/components/AppCanvas.tsx b/tldraw/packages/react/src/components/AppCanvas.tsx index 91940c94084..76a43027130 100644 --- a/tldraw/packages/react/src/components/AppCanvas.tsx +++ b/tldraw/packages/react/src/components/AppCanvas.tsx @@ -27,6 +27,7 @@ export const AppCanvas = observer(function InnerApp( shapes={app.shapes} // TODO: use shapes in viewport later? assets={app.assets} showGrid={app.settings.showGrid} + penMode={app.settings.penMode} showSelection={app.showSelection} showSelectionRotation={app.showSelectionRotation} showResizeHandles={app.showResizeHandles} diff --git a/tldraw/packages/react/src/components/Canvas/Canvas.tsx b/tldraw/packages/react/src/components/Canvas/Canvas.tsx index 5969563c624..0234b45dadf 100644 --- a/tldraw/packages/react/src/components/Canvas/Canvas.tsx +++ b/tldraw/packages/react/src/components/Canvas/Canvas.tsx @@ -58,6 +58,7 @@ export interface TLCanvasProps { cursorRotation: number selectionRotation: number onEditingEnd: () => void + penMode: boolean showGrid: boolean showSelection: boolean showHandles: boolean diff --git a/tldraw/packages/react/src/hooks/useCanvasEvents.ts b/tldraw/packages/react/src/hooks/useCanvasEvents.ts index 4fef6ee0ae4..5c596630883 100644 --- a/tldraw/packages/react/src/hooks/useCanvasEvents.ts +++ b/tldraw/packages/react/src/hooks/useCanvasEvents.ts @@ -13,11 +13,19 @@ export function useCanvasEvents() { const events = React.useMemo(() => { const onPointerMove: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerMove?.({ type: TLTargetType.Canvas, order }, e) } const onPointerDown: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e if (!order) e.currentTarget?.setPointerCapture(e.pointerId) @@ -41,17 +49,29 @@ export function useCanvasEvents() { } const onPointerUp: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e if (!order) e.currentTarget?.releasePointerCapture(e.pointerId) callbacks.onPointerUp?.({ type: TLTargetType.Canvas, order }, e) } const onPointerEnter: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerEnter?.({ type: TLTargetType.Canvas, order }, e) } const onPointerLeave: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerLeave?.({ type: TLTargetType.Canvas, order }, e) } diff --git a/tldraw/packages/react/src/hooks/useShapeEvents.ts b/tldraw/packages/react/src/hooks/useShapeEvents.ts index 99e38e839d2..81aaaa450d0 100644 --- a/tldraw/packages/react/src/hooks/useShapeEvents.ts +++ b/tldraw/packages/react/src/hooks/useShapeEvents.ts @@ -1,23 +1,33 @@ import * as React from 'react' import { TLTargetType } from '@tldraw/core' +import { useApp } from './useApp' import { useRendererContext } from '.' import { DOUBLE_CLICK_DURATION } from '../constants' import type { TLReactShape } from '../lib' import type { TLReactCustomEvents } from '../types' export function useShapeEvents(shape: S) { + const app = useApp() const { inputs, callbacks } = useRendererContext() const rDoubleClickTimer = React.useRef(-1) const events = React.useMemo(() => { const onPointerMove: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerMove?.({ type: TLTargetType.Shape, shape, order }, e) e.order = order + 1 } const onPointerDown: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e if (!order) e.currentTarget?.setPointerCapture(e.pointerId) callbacks.onPointerDown?.({ type: TLTargetType.Shape, shape, order }, e) @@ -25,6 +35,10 @@ export function useShapeEvents(shape: S) { } const onPointerUp: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e if (!order) e.currentTarget?.releasePointerCapture(e.pointerId) callbacks.onPointerUp?.({ type: TLTargetType.Shape, shape, order }, e) @@ -42,12 +56,20 @@ export function useShapeEvents(shape: S) { } const onPointerEnter: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerEnter?.({ type: TLTargetType.Shape, shape, order }, e) e.order = order + 1 } const onPointerLeave: TLReactCustomEvents['pointer'] = e => { + if (app.settings.penMode && (e.pointerType !== 'pen' || !e.isPrimary)) { + return + } + const { order = 0 } = e callbacks.onPointerLeave?.({ type: TLTargetType.Shape, shape, order }, e) e.order = order + 1