From 33a5febc7433e3b35dadaebef8395272c310c373 Mon Sep 17 00:00:00 2001
From: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Date: Thu, 28 Mar 2024 17:32:18 +0000
Subject: [PATCH] Add note preview handles for creating notes
---
packages/editor/api-report.md | 2 +-
packages/editor/api/api.json | 6 +-
packages/editor/editor.css | 4 ++
.../default-components/DefaultHandle.tsx | 60 +++++++++++++++----
.../src/lib/shapes/note/NoteShapeUtil.tsx | 7 ++-
5 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md
index c3a7827ab..14d61326d 100644
--- a/packages/editor/api-report.md
+++ b/packages/editor/api-report.md
@@ -466,7 +466,7 @@ export const DefaultErrorFallback: TLErrorFallbackComponent;
export function DefaultGrid({ x, y, z, size }: TLGridProps): JSX_2.Element;
// @public (undocumented)
-export function DefaultHandle({ handle, isCoarse, className, zoom }: TLHandleProps): JSX_2.Element;
+export function DefaultHandle({ handle, isCoarse, className, zoom }: TLHandleProps): JSX_2.Element | null;
// @public (undocumented)
export const DefaultHandles: ({ children }: TLHandlesProps) => JSX_2.Element;
diff --git a/packages/editor/api/api.json b/packages/editor/api/api.json
index 135223a10..ea39f4eac 100644
--- a/packages/editor/api/api.json
+++ b/packages/editor/api/api.json
@@ -6378,6 +6378,10 @@
"text": "JSX.Element",
"canonicalReference": "@types/react!JSX.Element:interface"
},
+ {
+ "kind": "Content",
+ "text": " | null"
+ },
{
"kind": "Content",
"text": ";"
@@ -6386,7 +6390,7 @@
"fileUrlPath": "packages/editor/src/lib/components/default-components/DefaultHandle.tsx",
"returnTypeTokenRange": {
"startIndex": 3,
- "endIndex": 5
+ "endIndex": 6
},
"releaseTag": "Public",
"overloadIndex": 1,
diff --git a/packages/editor/editor.css b/packages/editor/editor.css
index a5ecddfd5..d063bf24d 100644
--- a/packages/editor/editor.css
+++ b/packages/editor/editor.css
@@ -520,12 +520,16 @@ input,
pointer-events: none;
}
+
.tl-handle__create {
opacity: 0;
}
.tl-handle__create:hover {
opacity: 1;
}
+.tl-handle__note-create:hover {
+ opacity: 0.1;
+}
.tl-handle__bg:active {
fill: none;
diff --git a/packages/editor/src/lib/components/default-components/DefaultHandle.tsx b/packages/editor/src/lib/components/default-components/DefaultHandle.tsx
index 29d9bf8f6..e21ff2b3d 100644
--- a/packages/editor/src/lib/components/default-components/DefaultHandle.tsx
+++ b/packages/editor/src/lib/components/default-components/DefaultHandle.tsx
@@ -1,6 +1,8 @@
-import { TLHandle, TLShapeId } from '@tldraw/tlschema'
+import { TLHandle, TLShape, TLShapeId, getDefaultColorTheme } from '@tldraw/tlschema'
import classNames from 'classnames'
import { COARSE_HANDLE_RADIUS, HANDLE_RADIUS } from '../../constants'
+import { useEditor } from '../../hooks/useEditor'
+import { Box } from '../../primitives/Box'
/** @public */
export type TLHandleProps = {
@@ -10,23 +12,59 @@ export type TLHandleProps = {
isCoarse: boolean
className?: string
}
-
+export type NoteHandleId =
+ | 'note-button-up'
+ | 'note-preview-up'
+ | 'note-button-down'
+ | 'note-preview-down'
+ | 'note-button-left'
+ | 'note-preview-left'
+ | 'note-button-right'
+ | 'note-preview-right'
/** @public */
export function DefaultHandle({ handle, isCoarse, className, zoom }: TLHandleProps) {
const bgRadius = (isCoarse ? COARSE_HANDLE_RADIUS : HANDLE_RADIUS) / zoom
const fgRadius = (handle.type === 'create' && isCoarse ? 3 : 4) / zoom
-
+ const editor = useEditor()
// todo: this is bad
// @ts-expect-error
if (handle.type === 'note-create') {
- return (
-
- )
+ const noteShape = editor.getSelectedShapes()
+ const getNoteBox = (id: string, shape: TLShape) => {
+ switch (id) {
+ case 'note-preview-up':
+ return new Box(shape.x, shape.y - 230, 200, 200).expandBy(20)
+ case 'note-preview-down':
+ return new Box(shape.x, shape.y + 230, 200, 200).expandBy(20)
+ case 'note-preview-left':
+ return new Box(shape.x - 230, shape.y, 200, 200).expandBy(20)
+ case 'note-preview-right':
+ return new Box(shape.x + 230, shape.y, 200, 200).expandBy(20)
+ default:
+ throw new Error('Invalid note handle id')
+ }
+ }
+ const noteBox = getNoteBox(handle.id, noteShape[0])
+ const overlappingShapes = editor.getCurrentPageShapes().map((shape) => {
+ const bounds = editor.getShapePageBounds(shape)
+ if (bounds) {
+ return noteBox.contains(bounds)
+ } else return false
+ })
+
+ const shapesOverlapping = overlappingShapes.some(Boolean)
+ const theme = getDefaultColorTheme({ isDarkMode: editor.user.getIsDarkMode() })
+ if (!shapesOverlapping) {
+ return (
+
+ )
+ } else return null
}
return (
diff --git a/packages/tldraw/src/lib/shapes/note/NoteShapeUtil.tsx b/packages/tldraw/src/lib/shapes/note/NoteShapeUtil.tsx
index a88814997..4c165730a 100644
--- a/packages/tldraw/src/lib/shapes/note/NoteShapeUtil.tsx
+++ b/packages/tldraw/src/lib/shapes/note/NoteShapeUtil.tsx
@@ -6,6 +6,7 @@ import {
TLHandle,
TLNoteShape,
TLOnEditEndHandler,
+ createShapeId,
getDefaultColorTheme,
noteShapeMigrations,
noteShapeProps,
@@ -20,7 +21,7 @@ import { getFontDefForExport } from '../shared/defaultStyleDefs'
export const NOTE_SIZE = 200
export const NOTE_GRID_OFFSET = 230
-type NoteHandleId =
+export type NoteHandleId =
| 'note-button-up'
| 'note-preview-up'
| 'note-button-down'
@@ -242,7 +243,9 @@ export class NoteShapeUtil extends ShapeUtil {
}
}
const offset = getOffset(handleId, shape)
- this.editor.createShape({ type: 'note', x: offset.x, y: offset.y })
+ const id = createShapeId()
+ this.editor.createShape({ id, type: 'note', x: offset.x, y: offset.y })
+ this.editor.select(id)
}
override onDoubleClickHandle = (shape: TLNoteShape) => {
return shape