|
9 | 9 | * Copyright (c) Facebook, Inc. and its affiliates. |
10 | 10 | */ |
11 | 11 |
|
12 | | -import {useRef, useLayoutEffect, Fragment} from 'react'; |
| 12 | +import {useRef, useLayoutEffect, Fragment, useState, useEffect} from 'react'; |
13 | 13 |
|
14 | 14 | import cn from 'classnames'; |
15 | 15 | import {useRouter} from 'next/router'; |
@@ -78,6 +78,67 @@ function CollapseWrapper({ |
78 | 78 | ); |
79 | 79 | } |
80 | 80 |
|
| 81 | +interface ExpandableSidebarItemProps { |
| 82 | + title: string; |
| 83 | + path: string; |
| 84 | + level: number; |
| 85 | + routes?: RouteItem[]; |
| 86 | + version?: 'canary' | 'major' | 'experimental' | 'rc'; |
| 87 | + isForceExpanded: boolean; |
| 88 | + breadcrumbs: RouteItem[]; |
| 89 | + selected: boolean; |
| 90 | + pendingRoute: string | null; |
| 91 | +} |
| 92 | + |
| 93 | +function ExpandableSidebarItem({ |
| 94 | + title, |
| 95 | + path, |
| 96 | + level, |
| 97 | + routes, |
| 98 | + version, |
| 99 | + isForceExpanded, |
| 100 | + breadcrumbs, |
| 101 | + selected, |
| 102 | + pendingRoute, |
| 103 | +}: ExpandableSidebarItemProps) { |
| 104 | + const isBreadcrumb = |
| 105 | + breadcrumbs.length > 1 && |
| 106 | + breadcrumbs[breadcrumbs.length - 1].path === path; |
| 107 | + const defaultExpanded = isForceExpanded || isBreadcrumb || selected; |
| 108 | + const [isExpanded, setIsExpanded] = useState(defaultExpanded); |
| 109 | + |
| 110 | + useEffect(() => { |
| 111 | + if (defaultExpanded) { |
| 112 | + setIsExpanded(true); |
| 113 | + } |
| 114 | + }, [defaultExpanded]); |
| 115 | + |
| 116 | + return ( |
| 117 | + <li key={`${title}-${path}-${level}-heading`}> |
| 118 | + <SidebarLink |
| 119 | + key={`${title}-${path}-${level}-link`} |
| 120 | + href={path} |
| 121 | + isPending={pendingRoute === path} |
| 122 | + selected={selected} |
| 123 | + level={level} |
| 124 | + title={title} |
| 125 | + version={version} |
| 126 | + isExpanded={isExpanded} |
| 127 | + hideArrow={isForceExpanded} |
| 128 | + onToggle={() => setIsExpanded(!isExpanded)} |
| 129 | + /> |
| 130 | + <CollapseWrapper duration={250} isExpanded={isExpanded}> |
| 131 | + <SidebarRouteTree |
| 132 | + isForceExpanded={isForceExpanded} |
| 133 | + routeTree={{title, routes}} |
| 134 | + breadcrumbs={breadcrumbs} |
| 135 | + level={level + 1} |
| 136 | + /> |
| 137 | + </CollapseWrapper> |
| 138 | + </li> |
| 139 | + ); |
| 140 | +} |
| 141 | + |
81 | 142 | export function SidebarRouteTree({ |
82 | 143 | isForceExpanded, |
83 | 144 | breadcrumbs, |
@@ -116,32 +177,19 @@ export function SidebarRouteTree({ |
116 | 177 | ); |
117 | 178 | } else if (routes) { |
118 | 179 | // if route has a path and child routes, treat it as an expandable sidebar item |
119 | | - const isBreadcrumb = |
120 | | - breadcrumbs.length > 1 && |
121 | | - breadcrumbs[breadcrumbs.length - 1].path === path; |
122 | | - const isExpanded = isForceExpanded || isBreadcrumb || selected; |
123 | 180 | listItem = ( |
124 | | - <li key={`${title}-${path}-${level}-heading`}> |
125 | | - <SidebarLink |
126 | | - key={`${title}-${path}-${level}-link`} |
127 | | - href={path} |
128 | | - isPending={pendingRoute === path} |
129 | | - selected={selected} |
130 | | - level={level} |
131 | | - title={title} |
132 | | - version={version} |
133 | | - isExpanded={isExpanded} |
134 | | - hideArrow={isForceExpanded} |
135 | | - /> |
136 | | - <CollapseWrapper duration={250} isExpanded={isExpanded}> |
137 | | - <SidebarRouteTree |
138 | | - isForceExpanded={isForceExpanded} |
139 | | - routeTree={{title, routes}} |
140 | | - breadcrumbs={breadcrumbs} |
141 | | - level={level + 1} |
142 | | - /> |
143 | | - </CollapseWrapper> |
144 | | - </li> |
| 181 | + <ExpandableSidebarItem |
| 182 | + key={`${title}-${path}-${level}-heading`} |
| 183 | + title={title} |
| 184 | + path={path} |
| 185 | + level={level} |
| 186 | + routes={routes} |
| 187 | + version={version} |
| 188 | + isForceExpanded={isForceExpanded} |
| 189 | + breadcrumbs={breadcrumbs} |
| 190 | + selected={selected} |
| 191 | + pendingRoute={pendingRoute} |
| 192 | + /> |
145 | 193 | ); |
146 | 194 | } else { |
147 | 195 | // if route has a path and no child routes, treat it as a sidebar link |
|
0 commit comments