Skip to content

Commit

Permalink
Add Table of Contents component
Browse files Browse the repository at this point in the history
Implement a fixed Table of Contents (TOC) for the current editing document.

* **App.svelte**
  - Import the new `TableOfContents` component.
  - Add the `TableOfContents` component to the DOM.

* **TableOfContents.svelte**
  - Create a new Svelte component for the Table of Contents.
  - Use the `getEditorContext` function to access the editor state.
  - Render a list of headings from the current document.
  - Add styles for the Table of Contents to be fixed on the side of the editor.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/aolyang/tiptap-contentful?shareId=XXXX-XXXX-XXXX-XXXX).
  • Loading branch information
aolyang committed Dec 13, 2024
1 parent 2f676a5 commit 67261dd
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
2 changes: 2 additions & 0 deletions example/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import { setEditorContext } from "@/states/toolbar"
import { createEditor } from "@/utils/editor"
import { aligns, headingLevels } from "@/utils/editor-presets"
import TableOfContents from "@/components/TableOfContents.svelte"
import { onMount } from "svelte"
/*
Expand Down Expand Up @@ -88,5 +89,6 @@
<div class="size-full overflow-y-auto px-4">
<div class="px-10 py-6 max-w-[826px] min-h-full mx-auto bg-white dark:bg-neutral-700 shadow-xl"
bind:this={divRef}></div>
<TableOfContents />
</div>
</div>
92 changes: 92 additions & 0 deletions example/src/components/TableOfContents.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<script lang="ts">
import { onMount } from "svelte";
import { getEditorContext } from "@/states/toolbar";
import EditorTransactionEvent from "@/components/EditorTransactionEvent.svelte";
const ctx = getEditorContext();
let headings: { level: number; text: string }[] = [];
const updateHeadings = () => {
const doc = ctx.editor.state.doc;
const newHeadings: { level: number; text: string }[] = [];
doc.descendants((node) => {
if (node.type.name === "heading") {
newHeadings.push({
level: node.attrs.level,
text: node.textContent,
});
}
});
headings = newHeadings;
};
onMount(() => {
updateHeadings();
});
</script>

<EditorTransactionEvent {updateHeadings} />

<div class="toc">
<h2>Table of Contents</h2>
<ul>
{#each headings as heading}
<li class="heading-{heading.level}">
<a href="#">{heading.text}</a>
</li>
{/each}
</ul>
</div>

<style>
.toc {
position: fixed;
top: 120px;
right: 20px;
width: 200px;
background: white;
border: 1px solid #ccc;
padding: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.toc h2 {
margin-top: 0;
}
.toc ul {
list-style: none;
padding-left: 0;
}
.toc li {
margin-bottom: 5px;
}
.toc .heading-1 {
font-weight: bold;
}
.toc .heading-2 {
padding-left: 10px;
}
.toc .heading-3 {
padding-left: 20px;
}
.toc .heading-4 {
padding-left: 30px;
}
.toc .heading-5 {
padding-left: 40px;
}
.toc .heading-6 {
padding-left: 50px;
}
</style>

0 comments on commit 67261dd

Please sign in to comment.