janosh / svelte-toc Goto Github PK
View Code? Open in Web Editor NEWSticky responsive table of contents component
Home Page: https://janosh.github.io/svelte-toc
License: MIT License
Sticky responsive table of contents component
Home Page: https://janosh.github.io/svelte-toc
License: MIT License
Is there any way to disable the on appear blur animation?
Hi, I've tried setting up the module as described in the README, but getting the following error when starting the app. I'm using webpack instead of SvelteKit, not sure if the error is due to an incompatibility of some sort:
Module not found: Error: Can't resolve '$app/stores' in '/Users/alex/work/personal/app/node_modules/svelte-toc'
resolve '$app/stores' in '/Users/alex/work/personal/app/node_modules/svelte-toc'
Parsed request is a module
using description file: /Users/alex/work/personal/app/node_modules/svelte-toc/package.json (relative path: .)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
...
I did find the relevant line in Toc.svelte, I just don't understand how this $app/stores
import works, I don't see it as a library in package.json, so I'm guessing it's some sort of magic that's not properly setup on my project?
Thanks
Hi there,
I trying to implement svelte-toc to my current work. Unfortunately, I experiencing strange behaviour.
When I navigating by a link to: /article
Then in svelte-toc I got data from the previous page (on that previous page, svelte-toc wasn't used).
If I refresh the page in the browser, then svelte-doc is loaded with the correct data.
If I just put the URL to the article in the browser and open the page that way, the correct data will be loaded also in that case.
What I see that makes a demo app different from my work is that I do not use mdsvex
, I get markdown data from 3rdparty APIs and I parse it with markdown-it
.
So my <Toc />
component is not in markdown, but above it (I do not have file +page.svx
, I using <Toc />
in +page.svelte
)
It's hard for me to reproduce it, as I cannot share backend/frontend data. And at the same time, I have no idea what reason for that behaviour.
I will be grateful for any tips on where to look for the cause
Regards
when I was in your web page I was trying to move around, and found out that.
when I click on Usage and back on Examples the highlight is still on Usage tables of content. and for another example
when you are on top, try clicking on the bottom line Test Page Navigation it was highlighting on Styling instead.
Allow users to pass in a slot component to customize how ToC items are rendered.
Hi XD
I have my own toc
workflow for a sveltkit app i'm making and I have everything taken care of up until the intersection observer to highlight the current on screen headers in the toc
...trying to figure out how to do it, but have no knowledge of intersection observers or using them with svelte...looking through your code and I'm not sure where that part begins...
In my toc
I am looping through an array objects:
[
{ level: 1, heading: 'Frequencies' },
{ level: 1, heading: 'Notes' },
{ level: 2, heading: 'Equivalence' },
{ level: 2, heading: 'Pitch Classes' },
{ level: 1, heading: 'The Keyboard' },
{ level: 1, heading: 'Two Zones' },
{ level: 2, heading: 'Zone 1' },
{ level: 2, heading: 'Zone 2' },
{ level: 2, heading: 'Zone 1 + Zone 2' },
// ...etc...
]
that is generated by a custom rehype plugin traversing some markdown...
I then loop through it in my toc.svelte file:
<div class='toc-box'>
{#each headings as {level, heading}}
<div class='heading'>
<a class='toc-link'
href={`/words/${slugify(title)}#${slugify(heading)}`}
>
<span class='toc-link-text'>{removeTags(heading)}</span>
</a>
</div>
{/each}
</div>
...and everything is almost all good when the slugified
href matches the current hash and I can click around and go to hash links and all that...still not perfect and prolly should use <ul>
's and <li>
's, making my own slugify()
function and it doesn't quite work right yet, but these are other issues...
The last big piece of the toc
puzzle is highlighting the toc
headers that are currently in the viewport...just not sure how to go about it...
...I'm looking through your code and I'm not sure where that part begins and how to adapt it to my array of objects. I also have a REPL I've put together by lifting a codepen that works and trying to make it work with svelte, but can't figure it out...
Svelte REPL:
https://svelte.dev/repl/7006d7890b964928b8f72622a3d067ac?version=3.42.5
Original Codepen:
https://codepen.io/bramus/pen/ExaEqMJ
If you don't have time or interest for this no worries, totally understand, but if you have any thoughts that you would be willing to share I am all ears :-)
Thank you!
Use Playwright + vitest.
First off, thanks for this great package.
I'm interested, though still learning Svelte (and CSS), in adding a prop for the following style
Lines 184 to 189 in 06da853
From issue #32, you say you'll accept PRs adding such features. And I'm happy submit a PR, but I need some guidance.
I assume something like
:where(aside.toc > nav) {
overflow-y: var(--toc-nav-overlfow);
...
}
is close to what I'm after. How does one set the default to scroll;
?
Thanks in advance for pointing me in the right direction.
Hi,
When using smart zoom (double-taped mouse) svelte-toc prevents scrolling down to the bottom of the page. The scroll position jumps up when the active header should change instead of scrolling down and changing the active header in svelte-toc.
I also find out, that if I do not wrap with a fixed position wrapper, then svelte-toc prevents scrolling the page more than the height of the ToC component.
I am having a weird issue on my website.
I've added svelte-toc on a +layout.svelte file, for a specific dynamic route that loads blog posts. It works well when in that page, but things start breaking when I try navigating to others.
Here's how I'm using it:
{#if post.showToc}
{post.showToc} <!-- added here for debugging purposes -->
<TableOfContents />
{/if}
And my TableOfContents.svelte component does this:
<Toc breakpoint={767}>
<strong class="title" slot="title">Table of Contents</strong>
<ListIcon slot="open-toc-icon" />
</Toc>
You can find the source code to reproduce it on my repo (made sure to use the toc
branch), and there's also a live preview of that branch
To reproduce it:
false
. Note that, when the variable is printed, it still says true, which means nothing inside that #if
block was updated.
In that specific example, there were console errors related to view transitions, but I've confirmed these are not related to the issue, they're actually caused by it.
I appreciate any help in figuring this out, and let me know if there's anything I can try on my end, or logs to obtain!
See the ToC in Pandas docs for what this behavior looks like.
Hi @janosh,
This is not about bugs or issues, but the discussions tab is not active in this repo.
Am I thinking if this will have any sense to add to svelte-toc or if not if you mind helping me do something like that with the current implementation?
What I need:
I need to wrap headers and their contents into HTML tags (preferably of the choice).
So if I have content like this:
<h1>title</h1>
<p>some text in paragraph</p>
<img />
<p>next paragraph</p>
<p>and one more paragraph</p>
<h2>title</h2>
<p>paragraph in subtitle>
<h3>3rd title</h3>
<p>dfdfd</p>
I would need to be wrapped like this:
<tag id='title'>
<h1>title</h1>
<p>some text in paragraph</p>
<img />
<p>next paragraph</p>
<p>and one more paragraph</p>
<tag id='title2>
<h2>title2</h2>
<p>paragraph in subtitle>
</tag>
</tag>
<tag id='last-title'>
<h1>last title</h1>
<p>some paragraph content</p>
</tag>
as that HTML tag of choice
Wrapping each header and its own child.
The biggest problem here is to detect 'child' of the header because, from a technical point of view, this is not the child but unrelated content.
Probably logic will need to be something like this:
<tag>
</tag>
beforeI think this is an unexpected behavior for a ToC and should be disabled by default.
My experience: My ToC keeps automatically moving up and down when I try to scroll it. (I scrolled the ToC, not the page)
I just can't find anything related to font-size on the doc. This is my current codes:
<script>
import Toc from 'svelte-toc';
import ListBullets from '~icons/ph/list-bullets';
</script>
<Toc
breakpoint="992"
flashClickedHeadingsFor="0"
--toc-font-size="var(--font-size-small)"
--toc-width="240px"
--toc-padding="var(--space-m)"
--toc-li-border-radius="0"
--toc-li-hover-bg="transparent"
--toc-li-hover-color="var(--primary-500)"
--toc-li-padding="var(--space-2xs) 0"
--toc-active-bg="transparent"
--toc-active-color="var(--primary-500)"
--toc-desktop-bg="var(--black-400)"
--toc-desktop-sticky-top="var(--scroll-padding)"
--toc-mobile-bottom="100px"
--toc-mobile-btn-border-radius="100%"
--toc-mobile-bg="var(--black-400)"
--toc-mobile-btn-bg="var(--primary-500)"
--toc-mobile-btn-padding="var(-space-m)">
<span class="toc-title mid-text" slot="title">
<ListBullets color="var(--text-color)" width="24" height="24" />
Contents</span>
<span slot="open-toc-icon">
<ListBullets color="var(--black-500)" width="24" height="24" />
</span>
</Toc>
<style>
.toc-title {
display: flex;
align-items: center;
gap: var(--space-xs);
font-family: 'Fancy';
}
</style>
Find out why IntersectionObserver
appears to have trouble identifying the active heading when scrolling to near the page bottom. Highlighted heading seems to jump erratically between last two items in ToC.
Hi Janosh,
Using your awesome Plugin for another project again.
Thought this might be a nice enhancement if it isn't already available.
I couldn't find anything in the docs so I thought it wasn't, apologies if it already is an option, in which case I'd be super grateful if you could let me know how :-)
Thank you for this great tool and plugin!
I've played around with it quite a long time as I am trying to use it for an interactive version of my bachelor thesis ToC.
I have a small issue that I haven't been able to fix in the past few hours and would love your input.
When I enter the component like so:
<Toc
desktop = {true},
headingSelector = {":is(h1, h2):not(.toc-exclude)"}
--toc-desktop-max-width = "300px";
/>
It first starts by using up its full height above the actual content.
This is actually also the case for the example code provided:
<Toc
--toc-desktop-aside-margin="10em 0 0 0"
--toc-desktop-sticky-top="3em"
--toc-desktop-width="15em"
/>
Though I am guessing I am too newbie to get it right.
I can make it work by setting it in an absolute
positioned div, but then it becomes unsticky.
Any advice on how to correctly do this would be greatly appreciated, thank you so much either way for this component!
Is it possible to:
Thank you for a great plugin!
I have tried implementing it on my website, but there seems to be a weird issue. When I switch from a page that needs the ToC to a one that doesn't, there is a brief moment where a Table of Contents for the latter page is loaded before the component disappears. The lag is noticeable.
You can try it by going to this page and navigating to the homepage.
I have included my component like this
Any thoughts on why this might be happening?
Hi, does this library support TypeScript?
I am getting errors when I import this library in my TypeScript project.
Hi,
I think it's possible that svelte-toc interferes with other anchor links and smooth scrolling to them in the document.
I add it inside a <body class='flex main-bg'>
like so:
<div class='w-50'>
<div
on:click="{() => showToc = !showToc}"
class='main-bg w-9 h-9 m-2 hover:cursor-pointer sticky top-0'>
<svg fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path>
</svg>
</div>
{#if showToc}
<Toc
title = {"Table of Contents"},
desktop = {true},
headingSelector = {":is(h1, h2, h3):not(.toc-exclude)"}
--toc-desktop-max-width = "20em"/>
{/if}
</div>
The former is just an icon-burger button.
If I comment out the above the other anchor links work as expected (smooth scroll to them).
I am using Svelte and Tailwind.
For me this isn't such a big deal due to the nature of my anchor links (just references and I have them on hover anyway) but I thought you might want to be aware of it.
I can provide a link to the document to see it live if you like.
Cheers, and thanks again for this component, it made my project so much nicer.
Add a prop hideWhenIntersecting
to allow passing in an array of HTML elements or a query selector whose matching DOM nodes cause sveltet-toc
to be hidden temporarily for as long as there is non-zero intersection as the user scrolls passed them. Useful for things like full-width banners and images over which a heading list looks out of place.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.