Skip to content

Commit 68272b7

Browse files
committed
Fix diff sidebar flash on page load
1 parent 0d907a2 commit 68272b7

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

src/features/sidebar/view/SecondarySplitHeader.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,12 @@ const ToggleDiffButton = ({
123123
isDiffAvailable: boolean
124124
}) => {
125125
const [isMac, setIsMac] = useState(false)
126+
// Prevent flash of button during SSR/hydration. Only render after client mount.
127+
const [mounted, setMounted] = useState(false)
126128
useEffect(() => {
127129
// checkIsMac uses window so we delay the check.
128130
const timeout = window.setTimeout(() => {
131+
setMounted(true)
129132
setIsMac(checkIsMac())
130133
}, 0)
131134
return () => window.clearTimeout(timeout)
@@ -138,6 +141,7 @@ const ToggleDiffButton = ({
138141
: isDiffbarOpen
139142
? "Hide changes"
140143
: "Show changes"
144+
if (!mounted) return null
141145
return (
142146
<Box sx={{ display: isSidebarTogglable ? "block" : "none" }}>
143147

src/features/sidebar/view/internal/secondary/Container.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useState, useEffect } from "react"
12
import { SxProps } from "@mui/system"
23
import { Box, Stack } from "@mui/material"
34
import { styled } from "@mui/material/styles"
@@ -18,15 +19,22 @@ const SecondaryContainer = ({
1819
children?: React.ReactNode,
1920
isSM: boolean,
2021
}) => {
22+
// Disable transitions on initial render to prevent layout shift
23+
const [enableTransitions, setEnableTransitions] = useState(false)
24+
useEffect(() => {
25+
// Enable transitions after first paint
26+
requestAnimationFrame(() => setEnableTransitions(true))
27+
}, [])
28+
2129
const sx = { overflow: "hidden" }
2230
return (
2331
<>
2432
<InnerSecondaryContainer
25-
2633
sidebarWidth={isSM ? sidebarWidth : 0}
2734
isSidebarOpen={isSM ? offsetContent: false}
2835
diffWidth={isSM ? (diffWidth || 0) : 0}
2936
isDiffOpen={isSM ? (offsetDiffContent || false) : false}
37+
enableTransitions={enableTransitions}
3038
sx={{ ...sx }}
3139
>
3240
{children}
@@ -43,19 +51,20 @@ interface WrapperStackProps {
4351
readonly isSidebarOpen: boolean
4452
readonly diffWidth: number
4553
readonly isDiffOpen: boolean
54+
readonly enableTransitions: boolean
4655
}
4756

4857
const WrapperStack = styled(Stack, {
49-
shouldForwardProp: (prop) => prop !== "isSidebarOpen" && prop !== "sidebarWidth" && prop !== "diffWidth" && prop !== "isDiffOpen"
50-
})<WrapperStackProps>(({ theme, sidebarWidth, isSidebarOpen, diffWidth, isDiffOpen }) => {
58+
shouldForwardProp: (prop) => prop !== "isSidebarOpen" && prop !== "sidebarWidth" && prop !== "diffWidth" && prop !== "isDiffOpen" && prop !== "enableTransitions"
59+
})<WrapperStackProps>(({ theme, sidebarWidth, isSidebarOpen, diffWidth, isDiffOpen, enableTransitions }) => {
5160
return {
52-
transition: theme.transitions.create(["margin", "width"], {
61+
transition: enableTransitions ? theme.transitions.create(["margin", "width"], {
5362
easing: theme.transitions.easing.sharp,
5463
duration: theme.transitions.duration.leavingScreen
55-
}),
64+
}) : "none",
5665
marginLeft: isSidebarOpen ? 0 : `-${sidebarWidth}px`,
5766
marginRight: isDiffOpen ? 0 : `-${diffWidth}px`,
58-
...((isSidebarOpen || isDiffOpen) && {
67+
...((isSidebarOpen || isDiffOpen) && enableTransitions && {
5968
transition: theme.transitions.create(["margin", "width"], {
6069
easing: theme.transitions.easing.easeOut,
6170
duration: theme.transitions.duration.enteringScreen,
@@ -69,13 +78,15 @@ const InnerSecondaryContainer = ({
6978
isSidebarOpen,
7079
diffWidth,
7180
isDiffOpen,
81+
enableTransitions,
7282
children,
7383
sx
7484
}: {
7585
sidebarWidth: number
7686
isSidebarOpen: boolean
7787
diffWidth: number
7888
isDiffOpen: boolean
89+
enableTransitions: boolean
7990
children: React.ReactNode
8091
sx?: SxProps
8192
}) => {
@@ -87,8 +98,9 @@ const InnerSecondaryContainer = ({
8798
isSidebarOpen={isSidebarOpen}
8899
diffWidth={diffWidth}
89100
isDiffOpen={isDiffOpen}
101+
enableTransitions={enableTransitions}
90102
sx={{ ...sx, width: "100%", overflowY: "auto" }}
91-
103+
92104
>
93105
<RaisedMainContent>
94106
{children}

src/features/sidebar/view/internal/tertiary/RightContainer.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client'
22

3+
import { useState, useEffect } from "react"
34
import { SxProps } from "@mui/system"
45
import { Drawer as MuiDrawer } from "@mui/material"
56
import { useTheme } from "@mui/material/styles"
@@ -15,6 +16,12 @@ const RightContainer = ({
1516
onClose?: () => void
1617
children?: React.ReactNode
1718
}) => {
19+
// Don't render drawer until client-side to prevent flash
20+
const [mounted, setMounted] = useState(false)
21+
useEffect(() => {
22+
requestAnimationFrame(() => setMounted(true))
23+
}, [])
24+
if (!mounted) return null
1825
return (
1926
<>
2027
<InnerRightContainer

0 commit comments

Comments
 (0)