Skip to content

Commit a9356e6

Browse files
committed
Fix sidebar on mobile
1 parent a26382c commit a9356e6

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

src/components/DeclarationsPage.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default function DeclarationsPage({ context }: { context: DeclarationsCon
5050
<PageGrid>
5151
<MobileSidebarOverlay data-open={sidebarOpen || undefined} onClick={closeSidebar} />
5252
<SidebarPanel data-open={sidebarOpen || undefined}>
53-
<DeclarationsSidebar onNavigate={closeSidebar} />
53+
<DeclarationsSidebar onNavigate={closeSidebar} sidebarOpen={sidebarOpen} />
5454
</SidebarPanel>
5555
<ContentColumn>
5656
<NavBar onMenuClick={openSidebar} />
@@ -104,11 +104,6 @@ const SidebarPanel = styled.div`
104104
&[data-open] {
105105
display: flex;
106106
}
107-
108-
> * {
109-
flex: 1;
110-
min-height: 0;
111-
}
112107
}
113108
`;
114109

src/components/DeclarationsSidebar.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ const ROW_HEIGHT = 28;
4747
const STATIC_BEFORE = 19;
4848
const STATIC_AFTER = 60;
4949

50-
export const DeclarationsSidebar = ({ onNavigate }: { onNavigate?: () => void }) => {
50+
export const DeclarationsSidebar = ({
51+
onNavigate,
52+
sidebarOpen,
53+
}: {
54+
onNavigate?: () => void;
55+
sidebarOpen?: boolean;
56+
}) => {
5157
const { declarations, game } = useContext(DeclarationsContext);
5258
const { filter, setFilter } = useContext(SidebarFilterContext);
5359
const { module: activeModule = "", scope = "" } = useParams();
@@ -191,6 +197,21 @@ export const DeclarationsSidebar = ({ onNavigate }: { onNavigate?: () => void })
191197
}
192198
}, [activeModule, scope, activeIndex, virtualizer]);
193199

200+
// When the mobile sidebar opens, the virtualizer's scroll element transitions
201+
// from display:none to display:flex. The element had zero dimensions while hidden,
202+
// so the virtualizer rendered no items and scrollTop was lost. Re-measure and
203+
// scroll to the active item.
204+
useEffect(() => {
205+
if (!sidebarOpen || !parentRef.current) return;
206+
const raf = requestAnimationFrame(() => {
207+
virtualizer.measure();
208+
if (activeIndex >= 0) {
209+
virtualizer.scrollToIndex(activeIndex, { align: "center" });
210+
}
211+
});
212+
return () => cancelAnimationFrame(raf);
213+
}, [sidebarOpen]);
214+
194215
const handleSidebarNavigate = useCallback(() => {
195216
navigatedFromSidebarRef.current = true;
196217
onNavigate?.();
@@ -312,6 +333,7 @@ const SidebarSearchInput = styled(SearchInput)`
312333
const SidebarList = styled.div`
313334
flex: 1;
314335
overflow: auto;
336+
overscroll-behavior: contain;
315337
`;
316338

317339
const SidebarUl = styled.ul`

src/components/layout/Sidebar.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ export const SidebarGroupHeader = styled.button`
9292
display: flex;
9393
align-items: center;
9494
gap: 4px;
95+
overflow: hidden;
96+
white-space: nowrap;
97+
text-overflow: ellipsis;
9598
transition: color 0.1s;
9699
97100
&:hover {
@@ -123,4 +126,10 @@ export const SidebarWrapper = styled.nav`
123126
top: 0;
124127
height: 100dvh;
125128
align-self: start;
129+
130+
@media (max-width: 768px) {
131+
margin-right: 0;
132+
flex: 1;
133+
min-height: 0;
134+
}
126135
`;

0 commit comments

Comments
 (0)