diff --git a/README.md b/README.md
index 3778cc9..b5e4b2a 100644
--- a/README.md
+++ b/README.md
@@ -85,24 +85,27 @@ ScrewFast is an open-source template designed for quick and efficient web projec
- Serves as a UI demonstration with no live back-end integration.
- [x] **Starlight Documentation Theme Integration**:
- - A sleek, user-friendly, full-featured documentation theme, which enhances the readability and usability of our documentation.
- - Offers a range of features such as site navigation, built-in search functionality, dark mode, syntax highlighting for code, and improved SEO.
- - Seamlessly integrates internationalization (i18n) to provide support for documentation in multiple languages, catering to a global audience.
- - Designed to facilitate ease of use while offering a modern aesthetic in both light and dark themes to accommodate user preferences.
+ - A sleek, user-friendly, full-featured documentation theme, which enhances the readability and usability of our documentation.
+ - Offers a range of features such as site navigation, built-in search functionality, dark mode, syntax highlighting for code, and improved SEO.
+ - Seamlessly integrates internationalization (i18n) to provide support for documentation in multiple languages, catering to a global audience.
+ - Designed to facilitate ease of use while offering a modern aesthetic in both light and dark themes to accommodate user preferences.
- [x] **Icon Set Component**:
- - Convenient and reusable Icon component that allows adding icons simply by providing a name prop.
- - Render any pre-defined icon SVG using `` in your Astro components.
- - The Icon Component offers a centralized location for all SVG Icons across the project in one TypeScript file - allowing unified updates and easy maintenance.
- - **Note:** Users have the option to use other community integrations like [astro-icons](https://github.com/natemoo-re/astro-icon). However, the author decided to create a custom icon set component for managing custom icons.
+ - Convenient and reusable Icon component that allows adding icons simply by providing a name prop.
+ - Render any pre-defined icon SVG using `` in your Astro components.
+ - The Icon Component offers a centralized location for all SVG Icons across the project in one TypeScript file - allowing unified updates and easy maintenance.
+ - **Note:** Developers have the option to use other community integrations like [astro-icons](https://github.com/natemoo-re/astro-icon). However, the author decided to create a custom icon set component for managing custom icons.
- [x] **Internationalization (i18n) Features**:
- - Integrates [Astro’s internationalization (i18n) features](https://docs.astro.build/en/guides/internationalization/).
- - Additionally, a custom LanguagePicker component has been developed to facilitate language selection.
+ - Integrates [Astro’s internationalization (i18n) features](https://docs.astro.build/en/guides/internationalization/).
+ - Additionally, a custom LanguagePicker component has been developed to facilitate language selection.
+
+- [x] **Dynamic Table of Contents (ToC) with Scroll Progress Indicator**:
+ - Enhances ease of navigation in insight posts by highlighting the relevant section in the ToC, and includes a progress indicator to visually represent scroll progress.
+ - Developers seeking alternatives might consider the [remark-toc](https://github.com/remarkjs/remark-toc) plugin.
### Planned Improvements
-- [ ] Implement a table of contents (ToC) sidebar for blog articles.
-
+- Currently, there are no planned improvements. We'll update this section as plans develop.
### Bug Fixes
- Currently, there are no known bugs. If you encounter any issues, please report them on our [issues page](https://github.com/mearashadowfax/ScrewFast/issues).
diff --git a/src/pages/insights/[...slug].astro b/src/pages/insights/[...slug].astro
index 95cb1a0..66b9921 100644
--- a/src/pages/insights/[...slug].astro
+++ b/src/pages/insights/[...slug].astro
@@ -82,6 +82,7 @@ const pageTitle: string = `${post.data.title} | ${SITE.title}`;
html {
scroll-behavior: smooth;
}
+
article h2,
article h3,
article h4,
@@ -91,21 +92,26 @@ const pageTitle: string = `${post.data.title} | ${SITE.title}`;
margin-top: 2.5rem;
scroll-margin-top: 3rem;
}
+
h2 {
font-size: 1.5rem;
line-height: 2rem;
}
+
h3 {
font-size: 1.25rem;
line-height: 1.75rem;
}
+
h4 {
font-size: 1.125rem;
line-height: 1.75rem;
}
+
p {
margin-top: 1.5rem;
}
+
@keyframes grow-progress {
from {
transform: scaleX(0);
@@ -114,20 +120,24 @@ const pageTitle: string = `${post.data.title} | ${SITE.title}`;
transform: scaleX(1);
}
}
+
#progress {
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: scroll(block root);
}
+
#toc li {
display: flex;
align-items: center;
opacity: 0.8;
transition: all 300ms var(--transition-cubic);
}
+
#toc li.selected {
opacity: 1;
}
+
#toc li svg {
width: 0;
height: 0;
@@ -135,6 +145,7 @@ const pageTitle: string = `${post.data.title} | ${SITE.title}`;
height 400ms var(--transition-cubic),
width 400ms var(--transition-cubic);
}
+
#toc li.selected svg {
width: 1.25rem;
height: 1.25rem;
@@ -159,67 +170,55 @@ const pageTitle: string = `${post.data.title} | ${SITE.title}`;
},
});
+ const SVG_HTML_STRING = '';
+
+ function setActiveLinkById(id: string | null) {
+ const listItems = document.querySelectorAll("#toc li");
+ listItems.forEach(item => item.classList.remove("selected"));
+
+ if (!id) return;
+
+ const activeLink = document.querySelector(`#toc a[href="#${id}"]`);
+
+ if (!activeLink) return;
+
+ const listItem = activeLink.parentElement;
+ listItem?.classList.add("selected");
+ }
+
document.addEventListener("DOMContentLoaded", function () {
// The article element that contains the Markdown content
const article: HTMLElement | null = document.querySelector("article");
-
// The ToC container