diff --git a/app/canvas/canvas.tsx b/app/canvas/canvas.tsx index d2ef343437..30d4136a82 100644 --- a/app/canvas/canvas.tsx +++ b/app/canvas/canvas.tsx @@ -28,8 +28,9 @@ import { usePublishSelectedInstanceDataRect, usePublishHoveredInstanceRect, usePublishHoveredInstanceData, - useTrackSelectedInstance, - useTrackHoveredInstance, + useSetSelectedInstance, + useSetHoveredInstance, + useUnselectInstance, } from "./shared/instance"; import { useUpdateStyle } from "./shared/style"; import { useTrackSelectedElement } from "./shared/use-track-selected-element"; @@ -110,13 +111,14 @@ const DesignMode = ({ treeId, project }: DesignModeProps) => { useDeleteInstance(); usePublishRootInstance(); useTrackSelectedElement(); - useTrackSelectedInstance(); + useSetSelectedInstance(); useTrackHoveredElement(); - useTrackHoveredInstance(); + useSetHoveredInstance(); useSync({ project }); useUpdateSelectedInstance(); usePublishSelectedInstanceDataRect(); usePublishHoveredInstanceRect(); + useUnselectInstance(); const elements = useElementsTree(); return ( // Using touch backend becuase html5 drag&drop doesn't fire drag events in our case diff --git a/app/canvas/shared/instance.ts b/app/canvas/shared/instance.ts index 529515dcdb..52ee8d8d32 100644 --- a/app/canvas/shared/instance.ts +++ b/app/canvas/shared/instance.ts @@ -238,28 +238,37 @@ export const usePublishHoveredInstanceRect = () => { useEffect(publishRect, [publishRect]); }; -export const useTrackHoveredInstance = () => { +export const useSetHoveredInstance = () => { const [rootInstance] = useRootInstance(); const [hoveredElement] = useHoveredElement(); const [, setHoveredInstance] = useHoveredInstance(); useEffect(() => { - if (rootInstance === undefined || hoveredElement === undefined) return; - const instance = findInstanceById(rootInstance, hoveredElement.id); - if (instance === undefined) return; + let instance; + if (rootInstance !== undefined && hoveredElement?.id) { + instance = findInstanceById(rootInstance, hoveredElement.id); + } setHoveredInstance(instance); }, [rootInstance, hoveredElement, setHoveredInstance]); }; -export const useTrackSelectedInstance = () => { +export const useSetSelectedInstance = () => { const [rootInstance] = useRootInstance(); const [selectedElement] = useSelectedElement(); const [, setSelectedInstance] = useSelectedInstance(); useEffect(() => { - if (selectedElement === undefined || rootInstance === undefined) return; - const instance = findInstanceById(rootInstance, selectedElement.id); - if (instance === undefined) return; + let instance; + if (rootInstance !== undefined && selectedElement?.id) { + instance = findInstanceById(rootInstance, selectedElement.id); + } setSelectedInstance(instance); }, [selectedElement, rootInstance]); }; + +export const useUnselectInstance = () => { + const [, setSelectedElement] = useSelectedElement(); + useSubscribe("unselectInstance", () => { + setSelectedElement(undefined); + }); +}; diff --git a/app/designer/designer.tsx b/app/designer/designer.tsx index 3d902f8ad4..f2814f61fb 100644 --- a/app/designer/designer.tsx +++ b/app/designer/designer.tsx @@ -3,12 +3,19 @@ import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { type Project, useSubscribe, usePublish } from "@webstudio-is/sdk"; import type { Config } from "~/config"; -import type { HoveredInstanceData, SelectedInstanceData } from "~/shared/canvas-components"; +import type { + HoveredInstanceData, + SelectedInstanceData, +} from "~/shared/canvas-components"; import { Box, Flex, Grid, type CSS } from "~/shared/design-system"; import interStyles from "~/shared/font-faces/inter.css"; import { SidebarLeft } from "./features/sidebar-left"; import { Inspector } from "./features/inspector"; -import { useHoveredInstanceData, useSelectedInstanceData, useSyncStatus } from "./shared/nano-states"; +import { + useHoveredInstanceData, + useSelectedInstanceData, + useSyncStatus, +} from "./shared/nano-states"; import { Topbar } from "./features/topbar"; import designerStyles from "./designer.css"; import { Breadcrumbs } from "./features/breadcrumbs"; @@ -48,10 +55,7 @@ const useSubscribeSelectedInstanceData = () => { const useSubscribeHoveredInstanceData = () => { const [, setValue] = useHoveredInstanceData(); - useSubscribe<"hoverInstance", HoveredInstanceData>( - "hoverInstance", - setValue - ); + useSubscribe<"hoverInstance", HoveredInstanceData>("hoverInstance", setValue); }; const useSubscribeSyncStatus = () => { @@ -163,7 +167,7 @@ export const Designer = ({ config, project }: DesignerProps) => { useSubscribeSyncStatus(); useSubscribeRootInstance(); useSubscribeSelectedInstanceData(); - useSubscribeHoveredInstanceData() + useSubscribeHoveredInstanceData(); useSubscribeBreakpoints(); const [publish, publishRef] = usePublish(); const [isPreviewMode] = useIsPreviewMode(); @@ -194,7 +198,7 @@ export const Designer = ({ config, project }: DesignerProps) => { publish={publish} />
- + void; + publish: Publish; }; -export const Workspace = ({ children, onTransitionEnd }: WorkspaceProps) => { +export const Workspace = ({ + children, + onTransitionEnd, + publish, +}: WorkspaceProps) => { const [zoom] = useZoom(); const [canvasWidth] = useCanvasWidth(); + + const handleWorkspaceClick = () => { + publish({ type: "unselectInstance" }); + }; + return ( - +