@@ -10,27 +10,27 @@ export const DashboardTableOfContents = component$(
1010 return (
1111 < div class = "space-y-2" >
1212 < div class = "font-medium" > On This Page</ div >
13- < TableOfContent headings = { headings } />
13+ < TableOfContents headings = { headings } />
1414 </ div >
1515 ) ;
1616 } ,
1717) ;
1818
19- type TableOfContentProps = { headings : ContentHeading [ ] } ;
19+ type TableOfContentsProps = { headings : ContentHeading [ ] } ;
20+
2021interface Node extends ContentHeading {
21- level : number ;
22- children : Array < Node > ;
22+ children : Node [ ] ;
2323 activeItem : string ;
2424}
2525type Tree = Array < Node > ;
26- export const TableOfContent = component$ < TableOfContentProps > ( ( props ) => {
27- const inifiniteStopper = props . headings . map ( ( heading ) => {
28- return { text : heading . text , id : heading . id , level : heading . level } ;
29- } ) ;
30- const itemIds = props . headings . map ( ( item ) => item . id ) ;
26+
27+ const TableOfContents = component$ < TableOfContentsProps > ( ( { headings } ) => {
28+ const sanitizedHeadings = headings . map ( ( { text, id, level } ) => ( { text, id, level } ) ) ;
29+ const itemIds = headings . map ( ( { id } ) => id ) ;
3130 const activeHeading = useActiveItem ( itemIds ) ;
32- const tree = getTree ( inifiniteStopper ) ;
33- return < RecursiveJSX tree = { tree [ 0 ] } activeItem = { activeHeading . value } /> ;
31+ const tree = buildTree ( sanitizedHeadings ) ;
32+ const fixStartingBug : Node = { ...tree , children : [ tree ] } ;
33+ return < RecursiveList tree = { fixStartingBug } activeItem = { activeHeading . value } /> ;
3434} ) ;
3535
3636function deltaToStrg (
@@ -55,7 +55,8 @@ function deltaToStrg(
5555 `bad headings: are downwards discontinous from: #${ currNode . id } to #${ nextNode . id } bc from ${ currNode . level } to ${ nextNode . level } ` ,
5656 ) ;
5757}
58- function getTree ( nodes : ContentHeading [ ] ) {
58+
59+ function buildTree ( nodes : ContentHeading [ ] ) {
5960 let currNode = nodes [ 0 ] as Node ;
6061 currNode . children = [ ] ;
6162 const tree = [ currNode ] ;
@@ -94,32 +95,31 @@ function getTree(nodes: ContentHeading[]) {
9495 }
9596 currNode = nextNode ;
9697 }
97- return tree ;
98+ return tree [ 0 ] ;
9899}
99- type RecursiveJSXProps = {
100+
101+ type RecursiveListProps = {
100102 tree : Node ;
101103 activeItem : string ;
102104 limit ?: number ;
103105} ;
104- const RecursiveJSX = component$ < RecursiveJSXProps > ( ( { tree , activeItem , limit = 3 } ) => {
105- const currNode : Node = tree ;
106- return currNode ?. children ?. length && currNode . level < limit ? (
107- < ul class = { cn ( 'm-0 list-none' , { 'pl-4' : currNode . level !== 1 } ) } >
108- { currNode . children . map ( ( childNode ) => {
109- return (
110- < li key = { currNode . id } class = { cn ( ' mt-0 list-none pt-2' ) } >
106+
107+ const RecursiveList = component$ < RecursiveListProps > (
108+ ( { tree , activeItem , limit = 3 } ) => {
109+ return tree ?. children ?. length && tree . level < limit ? (
110+ < ul class = { cn ( 'm-0 list-none' , { 'pl-4' : tree . level !== 1 } ) } >
111+ { tree . children . map ( ( childNode ) => (
112+ < li key = { childNode . id } class = " mt-0 list-none pt-2" >
111113 < Anchor node = { childNode } activeItem = { activeItem } />
112- { childNode . children . length ? (
113- < >
114- < RecursiveJSX tree = { childNode } activeItem = { activeItem } />
115- </ >
116- ) : null }
114+ { childNode . children . length > 0 && (
115+ < RecursiveList tree = { childNode } activeItem = { activeItem } />
116+ ) }
117117 </ li >
118- ) ;
119- } ) }
120- </ ul >
121- ) : null ;
122- } ) ;
118+ ) ) }
119+ </ ul >
120+ ) : null ;
121+ } ,
122+ ) ;
123123
124124const useActiveItem = ( itemIds : string [ ] ) => {
125125 const activeId = useSignal < string > ( '' ) ;
@@ -133,7 +133,7 @@ const useActiveItem = (itemIds: string[]) => {
133133 }
134134 } ) ;
135135 } ,
136- { rootMargin : ` 0% 0% -85% 0%` } ,
136+ { rootMargin : ' 0% 0% -85% 0%' } ,
137137 ) ;
138138
139139 itemIds . forEach ( ( id ) => {
@@ -155,35 +155,35 @@ const useActiveItem = (itemIds: string[]) => {
155155
156156 return activeId ;
157157} ;
158- type AnchorThingProps = {
158+
159+ type AnchorProps = {
159160 node : Node ;
160161 activeItem : string ;
161162} ;
162- export const Anchor = component$ < AnchorThingProps > ( ( props ) => {
163- const currNode = props . node ;
164- const activeItem = props . activeItem ;
165- const isActiveItem = currNode . id === `${ activeItem } ` ;
163+
164+ const Anchor = component$ < AnchorProps > ( ( { node, activeItem } ) => {
165+ const isActive = node . id === activeItem ;
166166 return (
167167 < a
168- href = { `#${ currNode . id } ` }
168+ href = { `#${ node . id } ` }
169169 onClick$ = { [
170170 $ ( ( ) => {
171- const element = document . getElementById ( currNode . id ) ;
171+ const element = document . getElementById ( node . id ) ;
172172 if ( element ) {
173173 const navbarHeight = 90 ;
174- const elementPosition =
174+ const position =
175175 element . getBoundingClientRect ( ) . top + window . scrollY - navbarHeight ;
176- window . scrollTo ( { top : elementPosition , behavior : 'auto' } ) ;
176+ window . scrollTo ( { top : position , behavior : 'auto' } ) ;
177177 }
178178 } ) ,
179179 ] }
180180 class = { cn (
181- currNode . level > 2 ? 'ml-4' : null ,
181+ node . level > 2 && 'ml-2' ,
182182 'inline-block no-underline transition-colors hover:text-foreground' ,
183- isActiveItem ? 'font-medium text-foreground' : 'text-muted-foreground' ,
183+ isActive ? 'font-medium text-foreground' : 'text-muted-foreground' ,
184184 ) }
185185 >
186- { currNode . text }
186+ { node . text }
187187 </ a >
188188 ) ;
189189} ) ;
0 commit comments