11'use client' ;
22
3- import type React from 'react' ;
4-
5- import { MobileMenuSheet } from '@/components/MobileMenu' ;
6- import { useIsMobile } from '@/hooks/useIsMobile' ;
3+ import { MobileMenuScript , useMobileMenuSheet } from '@/components/MobileMenu' ;
4+ import { Button } from '@/components/primitives' ;
75import { tcls } from '@/lib/tailwind' ;
6+ import type React from 'react' ;
87import { TableOfContentsScript } from './TableOfContentsScript' ;
98
109export function TableOfContents ( props : {
1110 header ?: React . ReactNode ; // Displayed outside the scrollable TOC as a sticky header
1211 children : React . ReactNode ;
1312} ) {
1413 const { header, children } = props ;
15- const isMobile = useIsMobile ( ) ;
16-
17- // If the screen is mobile, we use the mobile menu sheet to display the table of contents.
18- if ( isMobile ) {
19- return < MobileMenuSheet > { children } </ MobileMenuSheet > ;
20- }
14+ const { open, setOpen } = useMobileMenuSheet ( ) ;
2115
2216 return (
2317 < >
18+ < div
19+ className = "fixed inset-0 z-40 bg-tint-12/4 backdrop-blur-lg data-[state=closed]:pointer-events-none data-[state=closed]:invisible data-[state=closed]:animate-fadeOut data-[state=open]:animate-fadeIn data-[state=open]:animate-in lg:hidden dark:bg-tint-1/6"
20+ data-state = { open ? 'open' : 'closed' }
21+ onClick = { ( ) => setOpen ( false ) }
22+ />
2423 < aside // Sidebar container, responsible for setting the right dimensions and position for the sidebar.
2524 data-testid = "table-of-contents"
2625 id = "table-of-contents"
26+ data-state = { open ? 'open' : 'closed' }
2727 className = { tcls (
2828 'group' ,
29+
30+ 'flex' ,
31+ 'flex-col' ,
32+
33+ 'max-lg:fixed' ,
34+ 'max-lg:z-50' ,
35+
36+ 'max-lg:transition' ,
37+ 'max-lg:ease-in-out' ,
38+ 'max-lg:duration-500' ,
39+
40+ 'max-lg:rounded-xl' ,
41+ 'max-lg:circular-corners:rounded-2xl' ,
42+ 'max-lg:straight-corners:rounded-none' ,
43+ 'max-lg:bg-tint-base' ,
44+ 'max-lg:sidebar-filled:bg-tint-subtle' ,
45+ 'max-lg:theme-muted:bg-tint-subtle' ,
46+ 'max-lg:[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle' ,
47+ 'max-lg:[html.sidebar-filled.theme-muted_&]:bg-tint-base' ,
48+ 'max-lg:[html.sidebar-filled.theme-bold.tint_&]:bg-tint-base' ,
49+
50+ 'max-lg:w-10/12' ,
51+ 'max-lg:shadow-lg' ,
52+ 'max-lg:depth-flat:shadow-none' ,
53+ 'max-lg:inset-1.5' ,
54+ 'max-lg:transition-all' ,
55+ 'max-lg:duration-300' ,
56+ 'max-lg:max-w-sm' ,
57+ 'max-lg:data-[state=open]:left-1.5' ,
58+ 'max-lg:data-[state=closed]:-left-full' ,
59+
2960 'text-sm' ,
3061
3162 'grow-0' ,
3263 'shrink-0' ,
33- 'basis-full' ,
3464 'lg:basis-72' ,
3565 'page-no-toc:lg:basis-56' ,
3666
37- 'relative' ,
38- 'z-[1]' ,
3967 'lg:sticky' ,
4068 'lg:mr-12' ,
4169
@@ -56,25 +84,37 @@ export function TableOfContents(props: {
5684 '[html[style*="--toc-top-offset"]_&]:lg:!top-[var(--toc-top-offset)]' ,
5785 '[html[style*="--toc-height"]_&]:lg:!h-[var(--toc-height)]' ,
5886
59- 'pt-6' ,
60- 'pb-4' ,
87+ 'lg: pt-6' ,
88+ 'lg: pb-4' ,
6189 'sidebar-filled:lg:pr-6' ,
6290 'page-no-toc:lg:pr-0' ,
6391
64- 'hidden' ,
65- 'lg:flex' ,
6692 'page-no-toc:lg:hidden' ,
6793 'page-no-toc:xl:flex' ,
6894 'site-header-none:page-no-toc:lg:flex' ,
69- 'flex-col' ,
7095 'gap-4' ,
7196 'border-tint-subtle'
7297 ) }
7398 >
7499 { header && header }
100+
101+ { open ? (
102+ < Button
103+ variant = "secondary"
104+ icon = "close"
105+ iconOnly
106+ autoFocus = { false }
107+ className = "absolute top-2 right-2 z-50 bg-transparent text-tint opacity-8 shadow-none ring-transparent"
108+ onClick = { ( ) => setOpen ( false ) }
109+ >
110+ < span className = "sr-only" > Close</ span >
111+ </ Button >
112+ ) : null }
113+
75114 { children }
76115 </ aside >
77116 < TableOfContentsScript />
117+ < MobileMenuScript />
78118 </ >
79119 ) ;
80120}
0 commit comments