Skip to content

Commit ccd47c4

Browse files
committed
fix: Improve grouped sidebar items collapsing (fixes #399)
1 parent f0e4849 commit ccd47c4

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

website/src/components/Sidebar.tsx

+32-19
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,18 @@ function SidebarGroup(props: { group: Pages[number] } & { depth: number }) {
8484
// A recursive function to determine if this group
8585
// has an active child link. If so, it is open.
8686
function hasActiveChild(pages: Pages): boolean {
87+
let isActive = false;
8788
for (const page of pages) {
8889
if ("group" in page) {
8990
if (hasActiveChild(page.pages)) {
90-
return true;
91+
isActive = true;
9192
}
9293
} else if (page.href) {
93-
return getHrefIsActive(ctx, router.asPath, page.href);
94+
isActive = getHrefIsActive(ctx, router.asPath, page.href);
9495
}
9596
}
96-
return false;
97+
98+
return isActive;
9799
}
98100

99101
// Determine if this group has an active child link.
@@ -122,6 +124,7 @@ function SidebarGroup(props: { group: Pages[number] } & { depth: number }) {
122124
depth={props.depth}
123125
href={props.group.href}
124126
icon={props.group.icon}
127+
isOpen={open}
125128
collapse={
126129
open ? <ChevronUpIcon size={14} /> : <ChevronDownIcon size={14} />
127130
}
@@ -142,26 +145,32 @@ function SidebarGroup(props: { group: Pages[number] } & { depth: number }) {
142145
function SidebarAnchor(props: {
143146
title: string;
144147
depth: number;
148+
isOpen?: boolean;
145149
href?: string;
146150
icon?: string;
147151
collapse?: ReactElement;
148152
onClick?: () => void;
149153
}) {
150154
const { href, isActive } = useHrefMeta(props.href ?? "");
151-
const className = cn("relative group flex items-center pr-5 gap-2 py-2 pl-3");
155+
const className = cn("py-2 inline-flex gap-2 grow");
156+
const style = {
157+
paddingLeft: `${(props.depth + 1) * 12}px`,
158+
};
152159

153160
const element = props.href ? (
154161
<Link
155162
href={href}
156-
onClick={props.collapse ? props.onClick : undefined}
163+
onClick={props.collapse && !props.isOpen ? props.onClick : undefined}
157164
className={cn(className, {
158165
"nav-link-active": isActive,
159166
})}
167+
style={style}
160168
/>
161169
) : (
162170
<div
163171
role="button"
164172
className={className}
173+
style={style}
165174
onKeyDown={props.onClick}
166175
onClick={props.onClick}
167176
/>
@@ -176,23 +185,27 @@ function SidebarAnchor(props: {
176185
<span key="title" className="flex-1 text-ellipsis overflow-hidden">
177186
{props.title}
178187
</span>,
179-
props.collapse ? (
180-
<div key="toggle" onKeyDown={props.onClick} onClick={props.onClick}>
181-
{props.collapse}
182-
</div>
183-
) : null,
184188
]);
185189

186190
return (
187-
<div className="opacity-75 has-[.nav-link-active]:opacity-100 hover:opacity-100 mb-px relative rounded-md hover:bg-black/5 dark:hover:bg-white/5 has-[.nav-link-active]:bg-primary-light/10 dark:has-[.nav-link-active]:bg-primary-light/10 dark:hover:has-[.nav-link-active]:bg-primary-light/10 transition-all">
188-
<div
189-
className="has-[.nav-link-active]:font-bold has-[.nav-link-active]:text-primary-light dark:has-[.nav-link-active]:text-primary-light"
190-
style={{
191-
paddingLeft: `${props.depth * 12}px`,
192-
}}
193-
>
194-
{anchor}
195-
</div>
191+
<div
192+
className={cn(
193+
"flex opacity-75 hover:opacity-100 mb-px relative rounded-md hover:bg-black/5 dark:hover:bg-white/5 transition-all has-[.nav-link-active]:font-bold",
194+
"has-[.nav-link-active]:opacity-100 has-[.nav-link-active]:bg-primary-light/10 dark:has-[.nav-link-active]:bg-primary-light/10 dark:hover:has-[.nav-link-active]:bg-primary-light/10 has-[.nav-link-active]:text-primary-light dark:has-[.nav-link-active]:text-primary-light"
195+
)}
196+
>
197+
{anchor}
198+
{props.collapse ? (
199+
<button
200+
key="toggle"
201+
type="button"
202+
onKeyDown={props.onClick}
203+
onClick={props.onClick}
204+
className="px-3"
205+
>
206+
{props.collapse}
207+
</button>
208+
) : null}
196209
</div>
197210
);
198211
}

0 commit comments

Comments
 (0)