From 5e8a5a48f27b86a5bce6d99c07f5f45631f367ac Mon Sep 17 00:00:00 2001 From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Date: Wed, 10 Aug 2022 19:07:15 +0100 Subject: [PATCH 1/5] Fix deleting newly placed components with Backspace key --- .../PageEditor/RenderPanel/RenderOverlay.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx index 0da48a4598e..b405b2dafd7 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx @@ -783,6 +783,8 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { ], ); + const overlayRef = React.useRef(null); + const handleNodeDrop = React.useCallback( (event: React.DragEvent) => { const cursorPos = canvasHostRef.current?.getViewCoordinates(event.clientX, event.clientY); @@ -1011,14 +1013,19 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { } } - api.dragEnd(); - if (selection) { deleteOrphanedLayoutComponents(draggedNode, dragOverNodeId); } + api.dragEnd(); + if (newNode) { api.select(newNode.id); + + const overlayElement = overlayRef.current; + if (overlayElement) { + overlayElement.focus(); + } } }, [ @@ -1309,6 +1316,7 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { return ( Date: Wed, 10 Aug 2022 19:34:27 +0100 Subject: [PATCH 2/5] Update RenderOverlay.tsx Signed-off-by: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> --- .../toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx index b405b2dafd7..d962f513d80 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx @@ -1022,6 +1022,7 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { if (newNode) { api.select(newNode.id); + // Refocus on overlay so that keyboard events can keep being caught by it const overlayElement = overlayRef.current; if (overlayElement) { overlayElement.focus(); From 0bc4e348cd24fdf554c0ae5e652ea971cc02e318 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Date: Tue, 16 Aug 2022 13:48:19 +0100 Subject: [PATCH 3/5] Add invariant checks for refs where possible --- .../AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx | 8 ++++++-- .../AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx | 10 +++++----- packages/toolpad-app/src/toolpad/Home.tsx | 6 +++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx index bb1be6234e3..ae0bbbedd93 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Grid, styled } from '@mui/material'; +import invariant from 'invariant'; export interface OverlayGridHandle { gridElement: HTMLDivElement | null; @@ -37,9 +38,12 @@ export const OverlayGrid = React.forwardRef(function OverlayG React.useImperativeHandle( forwardedRef, () => { + const gridElement = gridRef.current; + invariant(gridElement, 'Overlay grid ref not bound'); + let columnEdges: number[] = []; - if (gridRef.current) { - const gridColumnContainers = Array.from(gridRef.current.children); + if (gridElement) { + const gridColumnContainers = Array.from(gridElement.children); const gridColumnEdges = gridColumnContainers.map((container: Element) => { const containerRect = container.firstElementChild?.getBoundingClientRect(); return containerRect diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx index d962f513d80..972ef881bc3 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/RenderOverlay.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { NodeId } from '@mui/toolpad-core'; import { styled } from '@mui/material'; import clsx from 'clsx'; +import invariant from 'invariant'; import * as appDom from '../../../../appDom'; import { useDom, useDomApi } from '../../../DomLoader'; @@ -164,6 +165,8 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { const selectedNode = selection && appDom.getNode(dom, selection); + const overlayRef = React.useRef(null); + const draggedNode = React.useMemo( (): appDom.ElementNode | null => newNode || (draggedNodeId && appDom.getNode(dom, draggedNodeId, 'element')), @@ -783,8 +786,6 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { ], ); - const overlayRef = React.useRef(null); - const handleNodeDrop = React.useCallback( (event: React.DragEvent) => { const cursorPos = canvasHostRef.current?.getViewCoordinates(event.clientX, event.clientY); @@ -1024,9 +1025,8 @@ export default function RenderOverlay({ canvasHostRef }: RenderOverlayProps) { // Refocus on overlay so that keyboard events can keep being caught by it const overlayElement = overlayRef.current; - if (overlayElement) { - overlayElement.focus(); - } + invariant(overlayElement, 'Overlay ref not bound'); + overlayElement.focus(); } }, [ diff --git a/packages/toolpad-app/src/toolpad/Home.tsx b/packages/toolpad-app/src/toolpad/Home.tsx index d6fccc6ea0a..44505151739 100644 --- a/packages/toolpad-app/src/toolpad/Home.tsx +++ b/packages/toolpad-app/src/toolpad/Home.tsx @@ -27,6 +27,8 @@ import IconButton from '@mui/material/IconButton'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline'; import DeleteIcon from '@mui/icons-material/Delete'; +import invariant from 'invariant'; + import client from '../api'; import DialogForm from '../components/DialogForm'; import type { App, Deployment } from '../../prisma/generated/client'; @@ -213,7 +215,9 @@ function AppCard({ app, activeDeployment, onDelete }: AppCardProps) { ); React.useEffect(() => { - if (appTitleInput.current && editingTitle) { + invariant(appTitleInput.current, 'App title input ref not bound'); + + if (editingTitle) { appTitleInput.current.focus(); appTitleInput.current.select(); } From f58d34e1674ca26d739397fb59ffd43a5e7e8a59 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Date: Tue, 16 Aug 2022 13:51:18 +0100 Subject: [PATCH 4/5] Oopsy daisy --- .../PageEditor/RenderPanel/OverlayGrid.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx index ae0bbbedd93..a96cc0719bb 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/RenderPanel/OverlayGrid.tsx @@ -42,16 +42,14 @@ export const OverlayGrid = React.forwardRef(function OverlayG invariant(gridElement, 'Overlay grid ref not bound'); let columnEdges: number[] = []; - if (gridElement) { - const gridColumnContainers = Array.from(gridElement.children); - const gridColumnEdges = gridColumnContainers.map((container: Element) => { - const containerRect = container.firstElementChild?.getBoundingClientRect(); - return containerRect - ? [Math.round(containerRect.x), Math.round(containerRect.x + containerRect.width)] - : []; - }); - columnEdges = gridColumnEdges.flat(); - } + const gridColumnContainers = Array.from(gridElement.children); + const gridColumnEdges = gridColumnContainers.map((container: Element) => { + const containerRect = container.firstElementChild?.getBoundingClientRect(); + return containerRect + ? [Math.round(containerRect.x), Math.round(containerRect.x + containerRect.width)] + : []; + }); + columnEdges = gridColumnEdges.flat(); return { gridElement: gridRef.current, From 7a32d5ba1527a53b4eec2bac6844f59392ab2a23 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Date: Tue, 16 Aug 2022 13:55:13 +0100 Subject: [PATCH 5/5] Remove invariant check for app title --- packages/toolpad-app/src/toolpad/Home.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/toolpad-app/src/toolpad/Home.tsx b/packages/toolpad-app/src/toolpad/Home.tsx index 44505151739..d6fccc6ea0a 100644 --- a/packages/toolpad-app/src/toolpad/Home.tsx +++ b/packages/toolpad-app/src/toolpad/Home.tsx @@ -27,8 +27,6 @@ import IconButton from '@mui/material/IconButton'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline'; import DeleteIcon from '@mui/icons-material/Delete'; -import invariant from 'invariant'; - import client from '../api'; import DialogForm from '../components/DialogForm'; import type { App, Deployment } from '../../prisma/generated/client'; @@ -215,9 +213,7 @@ function AppCard({ app, activeDeployment, onDelete }: AppCardProps) { ); React.useEffect(() => { - invariant(appTitleInput.current, 'App title input ref not bound'); - - if (editingTitle) { + if (appTitleInput.current && editingTitle) { appTitleInput.current.focus(); appTitleInput.current.select(); }