@@ -58,8 +58,7 @@ export function TocPopover({ items, header, footer }: TOCProps): ReactElement {
5858 const { text } = useI18n ( ) ;
5959 const active = Primitive . useActiveAnchor ( ) ;
6060 const current = useMemo ( ( ) => {
61- if ( ! active ) return ;
62- return items . find ( ( item ) => item . url === `#${ active } ` ) ?. title ;
61+ return items . find ( ( item ) => active . includes ( item . url . slice ( 1 ) ) ) ?. title ;
6362 } , [ items , active ] ) ;
6463
6564 return (
@@ -99,18 +98,30 @@ function TOCItems({
9998} ) : React . ReactElement {
10099 const { text } = useI18n ( ) ;
101100 const containerRef = useRef < HTMLDivElement > ( null ) ;
102- const [ pos , setPos ] = useState < PosType > ( ) ;
101+ const [ pos , setPos ] = useState < PosType > ( [ 0 , 0 ] ) ;
103102 const active = Primitive . useActiveAnchor ( ) ;
104103
105104 useLayoutEffect ( ( ) => {
106105 const container = containerRef . current ;
107- if ( ! active || ! container ) return ;
106+ if ( active . length === 0 || ! container || container . clientHeight === 0 ) {
107+ setPos ( [ 0 , 0 ] ) ;
108+ return ;
109+ }
108110
109- const element : HTMLElement | null = container . querySelector (
110- `a[href="#${ active } "]` ,
111- ) ;
112- if ( ! element ) return ;
113- setPos ( [ element . offsetTop , element . clientHeight ] ) ;
111+ let upper = Number . MAX_VALUE ,
112+ lower = 0 ;
113+
114+ for ( const item of active ) {
115+ const element : HTMLElement | null = container . querySelector (
116+ `a[href="#${ item } "]` ,
117+ ) ;
118+ if ( ! element ) continue ;
119+
120+ upper = Math . min ( upper , element . offsetTop ) ;
121+ lower = Math . max ( lower , element . offsetTop + element . clientHeight ) ;
122+ }
123+
124+ setPos ( [ upper , lower - upper ] ) ;
114125 } , [ active ] ) ;
115126
116127 if ( items . length === 0 )
@@ -125,18 +136,17 @@ function TOCItems({
125136 < ScrollViewport className = "relative min-h-0 text-sm" ref = { containerRef } >
126137 < div
127138 role = "none"
128- className = "absolute start-0 w-0.5 bg-fd-primary transition-all"
139+ className = "absolute start-0 w-px bg-fd-primary transition-all"
129140 style = { {
130- top : pos ? `${ pos [ 0 ] . toString ( ) } px` : undefined ,
131- height : pos ? `${ pos [ 1 ] . toString ( ) } px` : undefined ,
132- display : pos ? 'block' : 'hidden' ,
141+ top : `${ pos [ 0 ] . toString ( ) } px` ,
142+ height : `${ pos [ 1 ] . toString ( ) } px` ,
133143 } }
134144 />
135145 < Primitive . ScrollProvider containerRef = { containerRef } >
136146 < div
137147 className = { cn (
138148 'flex flex-col gap-1 text-fd-muted-foreground' ,
139- ! isMenu && 'border-s-2 border-fd-foreground/10' ,
149+ ! isMenu && 'border-s border-fd-foreground/10' ,
140150 ) }
141151 >
142152 { items . map ( ( item ) => (
@@ -154,10 +164,10 @@ function TOCItem({ item }: { item: TOCItemType }): React.ReactElement {
154164 < Primitive . TOCItem
155165 href = { item . url }
156166 className = { cn (
157- 'py-1 transition-colors [overflow-wrap:anywhere] data-[active=true]:font-medium data-[active=true]:text-fd-primary' ,
158- item . depth <= 2 && 'ps-4 ' ,
159- item . depth === 3 && 'ps-7 ' ,
160- item . depth >= 4 && 'ps-10 ' ,
167+ 'py-0.5 transition-colors [overflow-wrap:anywhere] data-[active=true]:text-fd-primary' ,
168+ item . depth <= 2 && 'ps-3.5 ' ,
169+ item . depth === 3 && 'ps-6 ' ,
170+ item . depth >= 4 && 'ps-8 ' ,
161171 ) }
162172 >
163173 { item . title }
0 commit comments