fix: Show extended panels (#4493)

## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
This commit is contained in:
Ivan Starkov authored and GitHub committed 2024-12-02 17:36:16 +03:00
1 parent f837456d40
commit 539e083256
8 files changed
+80 -52

No files matched your search

+25 -20
View File
@@ -19,6 +19,7 @@ import { Topbar } from "./features/topbar";
import { Footer } from "./features/footer";
import {
CanvasIframe,
CanvasToolsContainer,
useReadCanvasRect,
Workspace,
} from "./features/workspace";
@@ -93,7 +94,6 @@ const SidePanel = ({
}: SidePanelProps) => {
return (
<Box
id="jopa"
as="aside"
css={{
position: "relative",
@@ -115,13 +115,14 @@ const SidePanel = ({
);
};
const Main = ({ children }: { children: ReactNode }) => (
const Main = ({ children, css }: { children: ReactNode; css?: CSS }) => (
<Flex
as="main"
direction="column"
css={{
gridArea: "main",
position: "relative",
...css,
}}
>
{children}
@@ -361,24 +362,6 @@ export const Builder = ({
navigatorLayout={navigatorLayout}
>
<ProjectSettings />
<Topbar
project={project}
hasProPlan={userPlanFeatures.hasProPlan}
css={{ gridArea: "header" }}
loading={
<LoadingBackground
// Looks nicer when topbar is already visible earlier, so user has more sense of progress.
show={
loadingState.readyStates.get("dataLoadingState")
? false
: true
}
/>
}
/>
<SidePanel gridArea="sidebar">
<SidebarLeft publish={publish} />
</SidePanel>
<Main>
<Workspace onTransitionEnd={onTransitionEnd}>
{dataLoadingState === "loaded" && (
@@ -392,6 +375,10 @@ export const Builder = ({
{isDesignMode && <AiCommandBar />}
</Main>
<SidePanel gridArea="sidebar">
<SidebarLeft publish={publish} />
</SidePanel>
<SidePanel
gridArea="inspector"
isPreviewMode={isPreviewMode}
@@ -411,6 +398,24 @@ export const Builder = ({
>
<Inspector navigatorLayout={navigatorLayout} />
</SidePanel>
<Main css={{ pointerEvents: "none" }}>
<CanvasToolsContainer />
</Main>
<Topbar
project={project}
hasProPlan={userPlanFeatures.hasProPlan}
css={{ gridArea: "header" }}
loading={
<LoadingBackground
// Looks nicer when topbar is already visible earlier, so user has more sense of progress.
show={
loadingState.readyStates.get("dataLoadingState")
? false
: true
}
/>
}
/>
{isPreviewMode === false && <Footer />}
<CloneProjectDialog
isOpen={isCloneDialogOpen}
@@ -87,14 +87,16 @@ export const MarketplacePanel = ({ onClose }: { onClose: () => void }) => {
<SpinnerIcon size={rawTheme.spacing[15]} />
</Flex>
)}
<ExtendedPanel isOpen={openAboutItem !== undefined}>
<About
item={openAboutItem}
onClose={() => {
setOpenAbout(undefined);
}}
/>
</ExtendedPanel>
{openAboutItem !== undefined && (
<ExtendedPanel>
<About
item={openAboutItem}
onClose={() => {
setOpenAbout(undefined);
}}
/>
</ExtendedPanel>
)}
</>
);
};
@@ -575,9 +575,8 @@ export const PagesPanel = ({ onClose }: { onClose: () => void }) => {
$editingPageId.set(itemId);
}}
/>
<ExtendedPanel isOpen={editingItemId !== undefined}>
{editingItemId !== undefined && (
{editingItemId !== undefined && (
<ExtendedPanel>
<>
{isFolder(editingItemId, pages.folders) ? (
<FolderEditor
@@ -591,8 +590,8 @@ export const PagesPanel = ({ onClose }: { onClose: () => void }) => {
/>
)}
</>
)}
</ExtendedPanel>
</ExtendedPanel>
)}
</>
);
};
@@ -5,6 +5,7 @@ import {
$instances,
$isPreviewMode,
$dragAndDropState,
$canvasToolsVisible,
} from "~/shared/nano-states";
import {
CollaborativeInstanceOutline,
@@ -37,11 +38,16 @@ const containerStyle = css({
export const CanvasTools = () => {
// @todo try to setup cross-frame atoms to avoid this
useSubscribeDragAndDropState();
const canvasToolsVisible = useStore($canvasToolsVisible);
const isPreviewMode = useStore($isPreviewMode);
const dragAndDropState = useStore($dragAndDropState);
const instances = useStore($instances);
const scale = useStore($scale);
if (!canvasToolsVisible) {
return;
}
if (
dragAndDropState.isDragging &&
dragAndDropState.placementIndicator !== undefined
@@ -83,7 +83,6 @@ const useOutlineStyle = () => {
return {
...style,
pointerEvents: "none",
width:
canvasWidth === undefined ? "100%" : (canvasWidth ?? 0) * (scale / 100),
} as const;
@@ -96,7 +95,6 @@ type WorkspaceProps = {
export const Workspace = ({ children, onTransitionEnd }: WorkspaceProps) => {
const canvasStyle = useCanvasStyle();
const outlineStyle = useOutlineStyle();
const workspaceRef = useMeasureWorkspace();
useSetCanvasWidth();
const handleWorkspaceClick = () => {
@@ -118,13 +116,23 @@ export const Workspace = ({ children, onTransitionEnd }: WorkspaceProps) => {
>
{children}
</div>
<div
data-name="canvas-tools-wrapper"
className={canvasContainerStyle()}
style={outlineStyle}
>
<CanvasTools />
</div>
</div>
</>
);
};
export const CanvasToolsContainer = () => {
const outlineStyle = useOutlineStyle();
useSetCanvasWidth();
return (
<>
<div
data-name="canvas-tools-wrapper"
className={canvasContainerStyle()}
style={outlineStyle}
>
<CanvasTools />
</div>
<Toaster />
</>
@@ -1,7 +1,8 @@
import { styled, Collapsible, Flex } from "@webstudio-is/design-system";
import { theme } from "@webstudio-is/design-system";
import { useRef } from "react";
import { useEffect, useRef } from "react";
import { BindingPopoverProvider } from "~/builder/shared/binding-popover";
import { $canvasToolsVisible } from "~/shared/nano-states";
const CollapsibleRoot = styled(Collapsible.Root, {
position: "absolute",
@@ -20,16 +21,20 @@ const CollapsibleContent = styled(Collapsible.Content, {
flexDirection: "column",
});
export const ExtendedPanel = ({
children,
isOpen,
}: {
children: React.ReactNode;
isOpen: boolean;
}) => {
export const ExtendedPanel = ({ children }: { children: React.ReactNode }) => {
const settingsRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// Quick workaround to hide the outline above extended panels.
// These panels should ideally be implemented as `Sheet`-style dialogs.
$canvasToolsVisible.set(false);
return () => {
$canvasToolsVisible.set(true);
};
}, []);
return (
<CollapsibleRoot ref={settingsRef} open={isOpen}>
<CollapsibleRoot ref={settingsRef} open={true}>
<CollapsibleContent>
<Flex
direction="column"
@@ -459,3 +459,5 @@ export const $dragAndDropState = atom<DragAndDropState>({
});
export const $marketplaceProduct = atom<undefined | MarketplaceProduct>();
export const $canvasToolsVisible = atom<boolean>(true);
@@ -128,6 +128,7 @@ const InternalToast = ({
css={{
display: "grid",
gridTemplateColumns: "8px 1fr",
pointerEvents: "all",
}}
>
<Box