Skip to content

Commit e3d6ec5

Browse files
authored
fix: rework sidebar menu responsive issues (#1928)
1 parent fc6e4c5 commit e3d6ec5

File tree

13 files changed

+152
-175
lines changed

13 files changed

+152
-175
lines changed

e2e/tests/hide-nav-bar.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const fixtureDir = path.resolve(__dirname, '../fixtures');
66
async function isNavBarVisible(page: Page): Promise<boolean> {
77
const nav = await page.$('.rspress-nav');
88
const className: string = await nav?.evaluate(el => el.className);
9-
109
return !className.includes('hidden');
1110
}
1211

@@ -36,7 +35,6 @@ test.describe('basic test', async () => {
3635
test('hideNavBar: "auto" should work', async ({ page }) => {
3736
await launchApp('./rspress-hide-auto.config.ts');
3837
await page.goto(`http://localhost:${appPort}/`);
39-
4038
await scrollDown(page);
4139
expect(await isNavBarVisible(page)).toBeFalsy();
4240
});

packages/theme-default/src/components/Nav/index.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
}
5959

6060
@media (max-width: 768px) {
61-
:root {
61+
html:root {
6262
--rp-nav-height: 56px;
6363
}
6464
.menu-item:before {

packages/theme-default/src/components/NavHamburger/index.module.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
.navHamburger:hover .middle {
2929
top: 6px;
3030
left: 0;
31-
transform: translateX(0);
31+
transform: translate3d(0, 0, 0);
3232
}
3333
.navHamburger:hover .bottom {
3434
top: 12px;
@@ -38,15 +38,15 @@
3838

3939
.navHamburger.active .top {
4040
top: 6px;
41-
transform: translateX(0) rotate(225deg);
41+
transform: translate3d(0, 0, 0) rotate(225deg);
4242
}
4343
.navHamburger.active .middle {
4444
top: 6px;
4545
transform: translateX(16px);
4646
}
4747
.navHamburger.active .bottom {
4848
top: 6px;
49-
transform: translateX(0) rotate(135deg);
49+
transform: translate3d(0, 0, 0) rotate(135deg);
5050
}
5151

5252
.navHamburger.active:hover .top,
@@ -74,7 +74,7 @@
7474
.top {
7575
top: 0;
7676
left: 0;
77-
transform: translateX(0);
77+
transform: translate3d(0, 0, 0);
7878
}
7979
.middle {
8080
top: 6px;

packages/theme-default/src/components/Overview/index.module.scss

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@
130130

131131
@media (max-width: 768px) {
132132
:global(.overview-index) {
133-
padding: 42px 24px;
134-
135133
h1 {
136134
font-size: 32px;
137135
margin-bottom: 24px;
@@ -159,7 +157,12 @@
159157
}
160158
}
161159

162-
@media (min-width: 1200px) {
160+
@media (min-width: 1280px) {
161+
:global(.overview-index) {
162+
padding-left: 2rem;
163+
padding-right: 2rem;
164+
}
165+
163166
.overview-groups {
164167
columns: 3;
165168
}

packages/theme-default/src/components/Overview/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ export function Overview(props: {
290290
const overviewTitle = title || 'Overview';
291291

292292
return (
293-
<div className="overview-index mx-auto px-8">
293+
<div className="overview-index mx-auto">
294294
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between mb-10">
295295
<h1 className="text-3xl leading-10 tracking-tight">{overviewTitle}</h1>
296296
{/* Added search input */}

packages/theme-default/src/components/Sidebar/index.module.scss

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
z-index: var(--rp-z-index-sidebar);
1414
width: calc(100vw - 64px);
1515
max-width: 320px;
16+
flex-shrink: 0;
1617
opacity: 0;
17-
transform: translateX(-100%);
18+
transform: translate3d(-100%, 0, 0);
1819
transition:
1920
opacity 0.5s,
2021
transform 0.25s ease;
@@ -30,7 +31,7 @@
3031
.sidebar.open {
3132
opacity: 1;
3233
visibility: visible;
33-
transform: translateX(0);
34+
transform: translate3d(0, 0, 0);
3435
transition:
3536
opacity 0.25s,
3637
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
@@ -46,20 +47,14 @@
4647
margin-top: calc(var(--rp-nav-height) * -1);
4748
height: 100vh;
4849
width: var(--rp-sidebar-width);
49-
transform: translateX(0);
50+
transform: translate3d(0, 0, 0);
5051
box-shadow: var(--rp-c-shadow-3);
5152
mask-image: linear-gradient(transparent, #000 20px),
5253
linear-gradient(270deg, #000 10px, transparent 0);
5354
--webkit-mask-image: linear-gradient(270deg, #000 10px, transparent 0);
5455
}
5556
}
5657

57-
@media (min-width: 1440px) {
58-
.sidebar {
59-
width: var(--rp-sidebar-width);
60-
}
61-
}
62-
6358
.menuLink {
6459
opacity: 1;
6560
}

packages/theme-default/src/components/SidebarMenu/index.scss

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Only appear on mobile
1+
// Only appear on <1280px screen width
22
.rspress-sidebar-menu {
33
position: sticky;
44
top: 0;
@@ -36,12 +36,18 @@
3636
z-index: var(--rp-z-index-backdrop);
3737
}
3838

39-
@media (min-width: 960px) {
39+
@media (min-width: 1280px) {
4040
.rspress-sidebar-menu {
4141
display: none;
4242
}
4343
}
4444

45+
@media (min-width: 960px) and (max-width: 1280px) {
46+
.rspress-sidebar-menu > button:first-child {
47+
display: none;
48+
}
49+
}
50+
4551
.rspress-local-toc-container {
4652
position: absolute;
4753
padding: 6px;
@@ -73,7 +79,7 @@
7379

7480
.fly-in-enter-active {
7581
opacity: 1;
76-
transform: translateX(0);
82+
transform: translate3d(0, 0, 0);
7783
transition:
7884
opacity 300ms,
7985
transform 300ms;
Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,42 @@
11
import { useLocation } from '@rspress/runtime';
2-
import { Sidebar, Toc } from '@theme';
2+
import { Toc } from '@theme';
33
import ArrowRight from '@theme-assets/arrow-right';
44
import MenuIcon from '@theme-assets/menu';
55
import { useEffect, useRef, useState } from 'react';
66
import './index.scss';
77
import type { UISwitchResult } from '../../logic/useUISwitch';
88
import { SvgWrapper } from '../SvgWrapper';
9+
import './index.scss';
910

11+
/* Top Menu, only displayed on <1280px screen width */
1012
export function SidebarMenu({
13+
isSidebarOpen,
14+
onIsSidebarOpenChange,
1115
outlineTitle,
12-
beforeSidebar,
13-
afterSidebar,
1416
uiSwitch,
15-
navTitle,
1617
}: {
18+
isSidebarOpen: boolean;
19+
onIsSidebarOpenChange: (isOpen: boolean) => void;
1720
outlineTitle: string;
18-
beforeSidebar?: React.ReactNode;
19-
afterSidebar?: React.ReactNode;
2021
uiSwitch?: UISwitchResult;
21-
navTitle?: React.ReactNode;
2222
}) {
23-
const [isSidebarOpen, setSidebarIsOpen] = useState<boolean>(false);
24-
const [isTocOpen, setIsTocOpen] = useState<boolean>(false);
2523
const tocContainerRef = useRef<HTMLDivElement>(null);
2624
const outlineButtonRef = useRef<HTMLButtonElement>(null);
25+
26+
const [isTocOpen, setIsTocOpen] = useState<boolean>(false);
27+
2728
const { pathname } = useLocation();
2829

2930
function openSidebar() {
30-
setSidebarIsOpen(true);
31+
onIsSidebarOpenChange(true);
3132
}
3233

3334
function closeSidebar() {
34-
setSidebarIsOpen(false);
35+
onIsSidebarOpenChange(false);
3536
}
3637

3738
useEffect(() => {
38-
setSidebarIsOpen(false);
39+
onIsSidebarOpenChange(false);
3940
}, [pathname]);
4041

4142
useEffect(() => {
@@ -61,70 +62,57 @@ export function SidebarMenu({
6162
};
6263

6364
return (
64-
<>
65-
{/* Top Menu, only displayed in mobile device */}
66-
<div className="rspress-sidebar-menu">
67-
{uiSwitch?.showSidebar ? (
65+
<div className="rspress-sidebar-menu">
66+
{uiSwitch?.showSidebar && (
67+
<>
6868
<button onClick={openSidebar} className="flex-center mr-auto">
6969
<div className="text-md mr-2">
7070
<SvgWrapper icon={MenuIcon} />
7171
</div>
7272
<span className="text-sm">Menu</span>
7373
</button>
74-
) : null}
75-
{uiSwitch?.showAside ? (
76-
<>
77-
<button
78-
onClick={() => setIsTocOpen(tocOpened => !tocOpened)}
79-
className="flex-center ml-auto"
80-
ref={outlineButtonRef}
81-
>
82-
<span className="text-sm">{outlineTitle}</span>
83-
<div
84-
className="text-md mr-2"
85-
style={{
86-
transform: isTocOpen ? 'rotate(90deg)' : 'rotate(0deg)',
87-
transition: 'transform 0.2s ease-out',
88-
marginTop: '2px',
89-
}}
90-
>
91-
<SvgWrapper icon={ArrowRight} />
92-
</div>
93-
</button>
94-
95-
<div
96-
className={`rspress-local-toc-container ${isTocOpen ? 'rspress-local-toc-container-show' : ''}`}
97-
>
98-
<Toc
99-
onItemClick={() => {
100-
setIsTocOpen(false);
101-
}}
102-
/>
103-
</div>
104-
</>
105-
) : null}
106-
</div>
107-
{/* Sidebar Component */}
108-
{uiSwitch?.showSidebar ? (
109-
<>
110-
<Sidebar
111-
isSidebarOpen={isSidebarOpen}
112-
beforeSidebar={beforeSidebar}
113-
afterSidebar={afterSidebar}
114-
uiSwitch={uiSwitch}
115-
navTitle={navTitle}
116-
/>
117-
{isSidebarOpen ? (
74+
{isSidebarOpen && (
11875
<div
11976
onClick={closeSidebar}
12077
className="rspress-sidebar-back-drop"
12178
style={{
12279
background: 'rgba(0, 0, 0, 0.6)',
12380
}}
12481
/>
125-
) : null}
82+
)}
83+
</>
84+
)}
85+
{uiSwitch?.showAside && (
86+
<>
87+
<button
88+
onClick={() => setIsTocOpen(tocOpened => !tocOpened)}
89+
className="flex-center ml-auto"
90+
ref={outlineButtonRef}
91+
>
92+
<span className="text-sm">{outlineTitle}</span>
93+
<div
94+
className="text-md mr-2"
95+
style={{
96+
transform: isTocOpen ? 'rotate(90deg)' : 'rotate(0deg)',
97+
transition: 'transform 0.2s ease-out',
98+
marginTop: '2px',
99+
}}
100+
>
101+
<SvgWrapper icon={ArrowRight} />
102+
</div>
103+
</button>
104+
105+
<div
106+
className={`rspress-local-toc-container ${isTocOpen ? 'rspress-local-toc-container-show' : ''}`}
107+
>
108+
<Toc
109+
onItemClick={() => {
110+
setIsTocOpen(false);
111+
}}
112+
/>
113+
</div>
126114
</>
127-
) : null}
128-
</>
115+
)}
116+
</div>
129117
);
130118
}

0 commit comments

Comments
 (0)