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