Skip to content

Commit 316b63f

Browse files
TheMcnafahamaiieul
andauthored
Toc readability (#858)
* docs(toc): improve code readability * fix(toc): workaround around bad template logic The alternative to this would be to create a conditional check that handles rendering the current node before calling the recursive step. This would require changing the template as JSX logic is awkard. --------- Co-authored-by: maiieul <[email protected]>
1 parent acf2ef2 commit 316b63f

File tree

1 file changed

+44
-44
lines changed
  • apps/website/src/components/toc

1 file changed

+44
-44
lines changed

apps/website/src/components/toc/toc.tsx

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2021
interface Node extends ContentHeading {
21-
level: number;
22-
children: Array<Node>;
22+
children: Node[];
2323
activeItem: string;
2424
}
2525
type 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

3636
function 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

124124
const 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

Comments
 (0)