Skip to content

Commit 4aa9012

Browse files
authored
chore(theme/sidebar): use 1fr to toggleCollapse the sidebarGroup (#2723)
1 parent f52964e commit 4aa9012

File tree

4 files changed

+54
-116
lines changed

4 files changed

+54
-116
lines changed

packages/core/src/theme/components/NavScreen/NavScreenMenuItem.scss

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,14 @@
4646

4747
&__group {
4848
width: 100%;
49+
}
4950

50-
height: 0px;
51+
&__group-inner {
5152
overflow: hidden;
52-
transition:
53-
height 0.3s ease,
54-
opacity 0.3s ease;
55-
5653
display: flex;
5754
flex-direction: column;
5855
align-items: center;
5956
gap: 2px;
60-
6157
margin-left: 8px;
62-
opacity: 0;
63-
64-
&--open {
65-
height: auto;
66-
opacity: 1;
67-
}
6858
}
6959
}

packages/core/src/theme/components/NavScreen/NavScreenMenuItem.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,22 @@ export function NavScreenMenuItemWithChildren({
114114
/>
115115

116116
<div
117-
className={`rp-nav-screen-menu-item__group ${isOpen ? 'rp-nav-screen-menu-item__group--open' : ''}`}
117+
className="rp-nav-screen-menu-item__group"
118+
style={{
119+
display: 'grid',
120+
gridTemplateRows: isOpen ? '1fr' : '0fr',
121+
transition: 'grid-template-rows .2s ease-out',
122+
width: '100%',
123+
}}
118124
>
119-
{menuItem.items.map(item => (
120-
<NavScreenMenuItemWithChildren
121-
key={item.text}
122-
menuItem={item as any}
123-
/>
124-
))}
125+
<div className="rp-nav-screen-menu-item__group-inner">
126+
{menuItem.items.map(item => (
127+
<NavScreenMenuItemWithChildren
128+
key={item.text}
129+
menuItem={item as any}
130+
/>
131+
))}
132+
</div>
125133
</div>
126134
</>
127135
) : (
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
11
.rp-sidebar-group {
22
color: var(--rp-c-text-1);
3-
font-weight: 400 !important;
4-
5-
&--top-level {
6-
font-weight: 400 !important;
7-
}
83
}

packages/core/src/theme/components/Sidebar/SidebarGroup.tsx

Lines changed: 37 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { useActiveMatcher } from '@rspress/core/runtime';
88
import ArrowRight from '@theme-assets/arrow-right';
99
import clsx from 'clsx';
1010
import type React from 'react';
11-
import { useCallback, useRef } from 'react';
1211
import { useNavigate } from '../Link/useNavigate';
1312
import { SvgWrapper } from '../SvgWrapper';
1413
import { SidebarDivider } from './SidebarDivider';
@@ -54,58 +53,10 @@ export function SidebarGroup(props: SidebarGroupProps) {
5453
const activeMatcher = useActiveMatcher();
5554
const { item, depth, id, setSidebarData, className } = props;
5655
const navigate = useNavigate();
57-
const initialState = useRef('collapsed' in item && item.collapsed);
58-
const containerRef = useRef<HTMLDivElement>(null);
59-
const containerHeightRef = useRef<number>(item.items.length * 40);
60-
61-
const transitionRef = useRef<number>(null);
6256
const active = item.link && activeMatcher(item.link);
6357
const { collapsed = false, collapsible = true } =
6458
item as NormalizedSidebarGroup;
6559

66-
const handleClickCollapsedTransition = useCallback(
67-
(collapsed: boolean /*target value */) => {
68-
if (transitionRef.current) {
69-
clearTimeout(transitionRef.current);
70-
}
71-
72-
const container = containerRef.current;
73-
74-
if (!container) {
75-
return;
76-
}
77-
78-
if (collapsed) {
79-
// fold
80-
const contentHeight = container.clientHeight;
81-
containerHeightRef.current = contentHeight;
82-
83-
container.style.maxHeight = `${contentHeight}px`;
84-
container.style.opacity = '0';
85-
container.style.transition = 'all .2s ease-out';
86-
87-
transitionRef.current = window.setTimeout(() => {
88-
if (containerRef.current) {
89-
containerRef.current.style.maxHeight = '0px';
90-
}
91-
}, 200);
92-
} else {
93-
// unfold
94-
const contentHeight = containerHeightRef.current;
95-
container.style.transition = 'all .2s ease-in';
96-
container.style.maxHeight = `${contentHeight}px`;
97-
container.style.opacity = '1';
98-
99-
transitionRef.current = window.setTimeout(() => {
100-
if (containerRef.current) {
101-
containerRef.current.style.removeProperty('max-height');
102-
}
103-
}, 200);
104-
}
105-
},
106-
[],
107-
);
108-
10960
const toggleCollapse = (): void => {
11061
// update collapsed state
11162
setSidebarData(sidebarData => {
@@ -132,13 +83,7 @@ export function SidebarGroup(props: SidebarGroupProps) {
13283
tag={item.tag}
13384
text={item.text}
13485
context={item.context}
135-
className={clsx(
136-
'rp-sidebar-group',
137-
{
138-
'rp-sidebar-group--top-level': depth === 0,
139-
},
140-
className,
141-
)}
86+
className={clsx('rp-sidebar-group', className)}
14287
depth={depth}
14388
onClick={e => {
14489
if (!active && item.link && !collapsed) {
@@ -149,55 +94,55 @@ export function SidebarGroup(props: SidebarGroupProps) {
14994
e.stopPropagation();
15095
navigate(item.link).then(() => {
15196
collapsible && toggleCollapse();
152-
collapsible && handleClickCollapsedTransition(!collapsed);
15397
});
15498
return;
15599
}
156100
e.stopPropagation();
157101
collapsible && toggleCollapse();
158-
collapsible && handleClickCollapsedTransition(!collapsed);
159102
}}
160103
right={collapsible && <CollapsibleIcon collapsed={collapsed} />}
161104
/>
162105

163106
<div
164-
ref={containerRef}
165107
style={{
166-
overflow: 'hidden',
167-
maxHeight: initialState.current ? '0px' : undefined,
168-
opacity: initialState.current ? 0 : 1,
108+
// Expand/collapse by animating grid-template-rows from 0fr to 1fr.
109+
display: 'grid',
110+
gridTemplateRows: collapsed ? '0fr' : '1fr',
111+
transition: 'grid-template-rows 0.2s ease-out',
169112
}}
170113
>
171-
{item.items?.map((item, index) =>
172-
isSidebarGroup(item) ? (
173-
<SidebarGroup
174-
id={`${id}-${index}`}
175-
depth={depth + 1}
176-
key={`${id}-${index}`}
177-
item={item}
178-
setSidebarData={setSidebarData}
179-
className="rp-sidebar-item--group-item"
180-
/>
181-
) : isSidebarDivider(item) ? (
182-
<SidebarDivider
183-
key={index}
184-
depth={depth + 1}
185-
dividerType={item.dividerType}
186-
/>
187-
) : isSidebarSectionHeader(item) ? (
188-
<SidebarSectionHeader
189-
sectionHeaderText={item.sectionHeaderText}
190-
key={index}
191-
/>
192-
) : (
193-
<SidebarItemComp
194-
key={index}
195-
item={item}
196-
depth={depth + 1}
197-
className="rp-sidebar-item--group-item"
198-
/>
199-
),
200-
)}
114+
<div style={{ overflow: 'hidden' }}>
115+
{item.items?.map((item, index) =>
116+
isSidebarGroup(item) ? (
117+
<SidebarGroup
118+
id={`${id}-${index}`}
119+
depth={depth + 1}
120+
key={`${id}-${index}`}
121+
item={item}
122+
setSidebarData={setSidebarData}
123+
className="rp-sidebar-item--group-item"
124+
/>
125+
) : isSidebarDivider(item) ? (
126+
<SidebarDivider
127+
key={index}
128+
depth={depth + 1}
129+
dividerType={item.dividerType}
130+
/>
131+
) : isSidebarSectionHeader(item) ? (
132+
<SidebarSectionHeader
133+
sectionHeaderText={item.sectionHeaderText}
134+
key={index}
135+
/>
136+
) : (
137+
<SidebarItemComp
138+
key={index}
139+
item={item}
140+
depth={depth + 1}
141+
className="rp-sidebar-item--group-item"
142+
/>
143+
),
144+
)}
145+
</div>
201146
</div>
202147
</>
203148
);

0 commit comments

Comments
 (0)