Skip to content

Commit 4c26097

Browse files
authored
fix: avoid left sidebar border covering the workspace outline (#4386)
## Description - use one border for both upper and lower part of the left sidebar menu - use box pseudo element instead of border to avoid overlapping 1 px of the workspace - make caret visible when user is editing content and parent has an instance outline from hover ## 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: 5de6) - [ ] 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
1 parent f36fe2f commit 4c26097

File tree

4 files changed

+96
-81
lines changed

4 files changed

+96
-81
lines changed

apps/builder/app/builder/builder.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ const SidePanel = ({
9696
//overflowY: "auto",
9797
bc: theme.colors.backgroundPanel,
9898
height: "100%",
99-
"&:last-of-type": {
100-
// Ensure content still has full width, avoid subpixels give layout round numbers
101-
boxShadow: `inset 1px 0 0 0 ${theme.colors.borderMain}`,
102-
},
10399
...css,
104100
}}
105101
>
@@ -410,7 +406,19 @@ export const Builder = ({
410406
<SidePanel
411407
gridArea="inspector"
412408
isPreviewMode={isPreviewMode}
413-
css={{ overflow: "hidden" }}
409+
css={{
410+
overflow: "hidden",
411+
// Drawing border this way to ensure content still has full width, avoid subpixels and give layout round numbers
412+
"&::after": {
413+
content: "''",
414+
position: "absolute",
415+
top: 0,
416+
left: 0,
417+
bottom: 0,
418+
width: 1,
419+
background: theme.colors.borderMain,
420+
},
421+
}}
414422
>
415423
<Inspector navigatorLayout={navigatorLayout} />
416424
</SidePanel>

apps/builder/app/builder/features/workspace/canvas-tools/outline/outline.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ const baseStyle = css({
3131
variants: {
3232
variant: {
3333
default: {
34-
outline: `1px solid ${theme.colors.backgroundPrimary}`,
34+
// Semi-transparent color allows user to see the carret when outlining content editable
35+
outline: `1px solid oklch(from ${theme.colors.backgroundPrimary} l c h / 0.7) `,
3536
outlineOffset: -1,
3637
},
3738
collaboration: {

apps/builder/app/builder/sidebar-left/sidebar-left.tsx

Lines changed: 71 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useRef, useState, type ReactNode } from "react";
2-
import { Box, Kbd, rawTheme, Text } from "@webstudio-is/design-system";
2+
import { Kbd, rawTheme, Text } from "@webstudio-is/design-system";
33
import { useSubscribe, type Publish } from "~/shared/pubsub";
44
import { $dragAndDropState, $isPreviewMode } from "~/shared/nano-states";
55
import { Flex } from "@webstudio-is/design-system";
@@ -183,80 +183,79 @@ export const SidebarLeft = ({ publish }: SidebarLeftProps) => {
183183
});
184184

185185
return (
186-
<Flex grow>
187-
<SidebarTabs
188-
activationMode="manual"
189-
value={activePanel}
190-
orientation="vertical"
191-
>
192-
{
193-
// In preview mode, we don't show left sidebar, but we want to allow pages panel to be open in the preview mode.
194-
// This way user can switch pages without exiting preview mode.
195-
}
196-
{isPreviewMode === false && (
197-
<>
198-
<ExternalDragDropMonitor />
199-
<div ref={tabsWrapperRef} style={{ display: "contents" }}>
200-
<SidebarTabsList>
201-
{panels.map(({ name, Icon, label }) => {
202-
return (
203-
<SidebarTabsTrigger
204-
key={name}
205-
label={label}
206-
value={name}
207-
onClick={() => {
208-
toggleActiveSidebarPanel(name);
209-
}}
210-
>
211-
<Icon size={rawTheme.spacing[10]} />
212-
</SidebarTabsTrigger>
213-
);
214-
})}
215-
</SidebarTabsList>
216-
</div>
217-
218-
<Box css={{ borderRight: `1px solid ${theme.colors.borderMain}` }}>
219-
<AiTabTrigger />
220-
<HelpTabTrigger />
221-
</Box>
222-
</>
223-
)}
186+
<SidebarTabs
187+
activationMode="manual"
188+
value={activePanel}
189+
orientation="vertical"
190+
>
191+
{
192+
// In preview mode, we don't show left sidebar, but we want to allow pages panel to be open in the preview mode.
193+
// This way user can switch pages without exiting preview mode.
194+
}
195+
{isPreviewMode === false && (
196+
<Flex
197+
grow
198+
direction="column"
199+
css={{ borderRight: `1px solid ${theme.colors.borderMain}` }}
200+
>
201+
<ExternalDragDropMonitor />
202+
<div ref={tabsWrapperRef} style={{ display: "contents" }}>
203+
<SidebarTabsList>
204+
{panels.map(({ name, Icon, label }) => {
205+
return (
206+
<SidebarTabsTrigger
207+
key={name}
208+
label={label}
209+
value={name}
210+
onClick={() => {
211+
toggleActiveSidebarPanel(name);
212+
}}
213+
>
214+
<Icon size={rawTheme.spacing[10]} />
215+
</SidebarTabsTrigger>
216+
);
217+
})}
218+
</SidebarTabsList>
219+
</div>
220+
<AiTabTrigger />
221+
<HelpTabTrigger />
222+
</Flex>
223+
)}
224224

225-
<SidebarTabsContent
226-
value={activePanel === "none" ? "" : activePanel}
227-
onKeyDown={(event) => {
228-
if (event.key === "Escape") {
229-
setActiveSidebarPanel("none");
230-
}
231-
}}
225+
<SidebarTabsContent
226+
value={activePanel === "none" ? "" : activePanel}
227+
onKeyDown={(event) => {
228+
if (event.key === "Escape") {
229+
setActiveSidebarPanel("none");
230+
}
231+
}}
232+
css={{
233+
width: theme.spacing[30],
234+
// We need the node to be rendered but hidden
235+
// to keep receiving the drag events.
236+
visibility:
237+
dragAndDropState.isDragging &&
238+
dragAndDropState.dragPayload?.origin === "panel" &&
239+
getSetting("navigatorLayout") !== "undocked"
240+
? "hidden"
241+
: "visible",
242+
}}
243+
>
244+
<Flex
232245
css={{
233-
width: theme.spacing[30],
234-
// We need the node to be rendered but hidden
235-
// to keep receiving the drag events.
236-
visibility:
237-
dragAndDropState.isDragging &&
238-
dragAndDropState.dragPayload?.origin === "panel" &&
239-
getSetting("navigatorLayout") !== "undocked"
240-
? "hidden"
241-
: "visible",
246+
position: "relative",
247+
height: "100%",
248+
flexGrow: 1,
249+
background: theme.colors.backgroundPanel,
242250
}}
251+
direction="column"
243252
>
244-
<Flex
245-
css={{
246-
position: "relative",
247-
height: "100%",
248-
flexGrow: 1,
249-
background: theme.colors.backgroundPanel,
250-
}}
251-
direction="column"
252-
>
253-
<Panel
254-
publish={publish}
255-
onClose={() => setActiveSidebarPanel("none")}
256-
/>
257-
</Flex>
258-
</SidebarTabsContent>
259-
</SidebarTabs>
260-
</Flex>
253+
<Panel
254+
publish={publish}
255+
onClose={() => setActiveSidebarPanel("none")}
256+
/>
257+
</Flex>
258+
</SidebarTabsContent>
259+
</SidebarTabs>
261260
);
262261
};

apps/builder/app/builder/sidebar-left/sidebar-tabs.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const SidebarTabs = styled(Tabs, {
1818
alignItems: "center",
1919
position: "relative",
2020
boxSizing: "border-box",
21+
flexGrow: 1,
2122
});
2223

2324
const triggerFocusRing = focusRingStyle();
@@ -93,7 +94,6 @@ export const SidebarTabsList = styled(TabsList, {
9394
flexDirection: "column",
9495
alignItems: "center",
9596
outline: "none",
96-
borderRight: `1px solid ${theme.colors.borderMain}`,
9797
flexGrow: 1,
9898
backgroundColor: theme.colors.backgroundPanel,
9999
});
@@ -106,7 +106,14 @@ export const SidebarTabsContent = styled(TabsContent, {
106106
height: "100%",
107107
bc: theme.colors.backgroundPanel,
108108
outline: "none",
109-
'&[data-state="active"]': {
110-
borderRight: `1px solid ${theme.colors.borderMain}`,
109+
// Drawing border this way to ensure content still has full width, avoid subpixels and give layout round numbers
110+
"&::after": {
111+
content: "''",
112+
position: "absolute",
113+
top: 0,
114+
right: 0,
115+
bottom: 0,
116+
width: 1,
117+
background: theme.colors.borderMain,
111118
},
112119
});

0 commit comments

Comments
 (0)