Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 64 additions & 57 deletions src/components/Layout/Sidebar/SidebarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface SidebarLinkProps {
icon?: React.ReactNode;
isExpanded?: boolean;
hideArrow?: boolean;
onToggle?: () => void;
isPending: boolean;
}

Expand All @@ -39,6 +40,7 @@ export function SidebarLink({
level,
isExpanded,
hideArrow,
onToggle,
isPending,
}: SidebarLinkProps) {
const ref = useRef<HTMLAnchorElement>(null);
Expand All @@ -58,67 +60,72 @@ export function SidebarLink({
target = '_blank';
}
return (
<Link
href={href}
ref={ref}
title={title}
target={target}
passHref
aria-current={selected ? 'page' : undefined}
className={cn(
'p-2 pe-2 w-full rounded-none lg:rounded-e-2xl text-start hover:bg-gray-5 dark:hover:bg-gray-80 relative flex items-center justify-between',
{
'text-sm ps-6': level > 0,
'ps-5': level < 2,
'text-base font-bold': level === 0,
'text-primary dark:text-primary-dark': level === 0 && !selected,
'text-base text-secondary dark:text-secondary-dark':
level > 0 && !selected,
'text-base text-link dark:text-link-dark bg-highlight dark:bg-highlight-dark border-blue-40 hover:bg-highlight hover:text-link dark:hover:bg-highlight-dark dark:hover:text-link-dark':
selected,
'dark:bg-gray-70 bg-gray-3 dark:hover:bg-gray-70 hover:bg-gray-3':
isPending,
}
)}>
{/* This here needs to be refactored ofc */}
<div>
{title}{' '}
{version === 'major' && (
<span
title="- This feature is available in React 19 beta and the React canary channel"
className={`text-xs px-1 ms-1 rounded bg-gray-10 dark:bg-gray-40 dark:bg-opacity-20 text-gray-40 dark:text-gray-40`}>
React 19
</span>
)}
{version === 'canary' && (
<IconCanary
title=" - This feature is available in the latest Canary version of React"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
{version === 'experimental' && (
<IconExperimental
title=" - This feature is available in the latest Experimental version of React"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
{version === 'rc' && (
<IconCanary
title=" - This feature is available in the latest RC version"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
</div>

{isExpanded != null && !hideArrow && (
<span
className={cn('pe-1', {
<div className="relative">
<Link
href={href}
ref={ref}
title={title}
target={target}
passHref
aria-current={selected ? 'page' : undefined}
className={cn(
'p-2 pe-2 w-full rounded-none lg:rounded-e-2xl text-start hover:bg-gray-5 dark:hover:bg-gray-80 relative flex items-center justify-between',
isExpanded != null && !hideArrow && 'pe-10',
{
'text-sm ps-6': level > 0,
'ps-5': level < 2,
'text-base font-bold': level === 0,
'text-primary dark:text-primary-dark': level === 0 && !selected,
'text-base text-secondary dark:text-secondary-dark':
level > 0 && !selected,
'text-base text-link dark:text-link-dark bg-highlight dark:bg-highlight-dark border-blue-40 hover:bg-highlight hover:text-link dark:hover:bg-highlight-dark dark:hover:text-link-dark':
selected,
'dark:bg-gray-70 bg-gray-3 dark:hover:bg-gray-70 hover:bg-gray-3':
isPending,
}
)}>
<div>
{title}{' '}
{version === 'major' && (
<span
title="- This feature is available in React 19 beta and the React canary channel"
className={`text-xs px-1 ms-1 rounded bg-gray-10 dark:bg-gray-40 dark:bg-opacity-20 text-gray-40 dark:text-gray-40`}>
React 19
</span>
)}
{version === 'canary' && (
<IconCanary
title=" - This feature is available in the latest Canary version of React"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
{version === 'experimental' && (
<IconExperimental
title=" - This feature is available in the latest Experimental version of React"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
{version === 'rc' && (
<IconCanary
title=" - This feature is available in the latest RC version"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
</div>
</Link>
{isExpanded != null && !hideArrow && onToggle != null && (
<button
type="button"
aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${title}`}
aria-expanded={isExpanded}
onClick={onToggle}
className={cn('absolute inset-y-0 end-0 flex items-center px-3', {
'text-link dark:text-link-dark': isExpanded,
'text-tertiary dark:text-tertiary-dark': !isExpanded,
})}>
<IconNavArrow displayDirection={isExpanded ? 'down' : 'end'} />
</span>
</button>
)}
</Link>
</div>
);
}
15 changes: 13 additions & 2 deletions src/components/Layout/Sidebar/SidebarRouteTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/

import {useRef, useLayoutEffect, Fragment} from 'react';
import {useRef, useLayoutEffect, useState, Fragment} from 'react';

import cn from 'classnames';
import {useRouter} from 'next/router';
Expand Down Expand Up @@ -87,6 +87,9 @@ export function SidebarRouteTree({
const slug = useRouter().asPath.split(/[\?\#]/)[0];
const pendingRoute = usePendingRoute();
const currentRoutes = routeTree.routes as RouteItem[];
const [expandedRoutes, setExpandedRoutes] = useState<Record<string, boolean>>(
{}
);
return (
<ul>
{currentRoutes.map(
Expand Down Expand Up @@ -119,7 +122,9 @@ export function SidebarRouteTree({
const isBreadcrumb =
breadcrumbs.length > 1 &&
breadcrumbs[breadcrumbs.length - 1].path === path;
const isExpanded = isForceExpanded || isBreadcrumb || selected;
const isExpanded =
isForceExpanded ||
(expandedRoutes[path] ?? (isBreadcrumb || selected));
listItem = (
<li key={`${title}-${path}-${level}-heading`}>
<SidebarLink
Expand All @@ -132,6 +137,12 @@ export function SidebarRouteTree({
version={version}
isExpanded={isExpanded}
hideArrow={isForceExpanded}
onToggle={() =>
setExpandedRoutes((previous) => ({
...previous,
[path]: !isExpanded,
}))
}
/>
<CollapseWrapper duration={250} isExpanded={isExpanded}>
<SidebarRouteTree
Expand Down
Loading