GithubHelp home page GithubHelp logo

janosh / svelte-toc Goto Github PK

View Code? Open in Web Editor NEW
107.0 5.0 6.0 470 KB

Sticky responsive table of contents component

Home Page: https://janosh.github.io/svelte-toc

License: MIT License

Svelte 39.72% JavaScript 3.49% HTML 3.35% CSS 15.56% TypeScript 37.89%
svelte sveltekit table-of-contents component sticky responsive-web-design toc

svelte-toc's Introduction

Logo
 Svelte ToC

Tests GitHub Pages pre-commit.ci status NPM version Open in StackBlitz REPL

Sticky responsive table of contents component. Live Demo

🔨   Installation

npm install --dev svelte-toc

📙   Usage

<script>
  import Toc from 'svelte-toc'
</script>

<Toc />

<main>
  <h1>Page Title</h1>
  <h2>Section</h2>
  <h3>Subsection</h3>
  <h2>Next Section</h2>
  <h3 class="toc-exclude">Another Subsection</h3>
</main>

🔣   Props

Full list of props and bindable variables for this component (all of them optional):

  1. activeHeading: HTMLHeadingElement | null = null

    The DOM node of the currently active (highlighted) heading (based on user's scroll position on the page).

  2. activeHeadingScrollOffset: number = 100

    Distance in pixels to top edge of screen at which a heading jumps from inactive to active. Increase this value if you have a header that makes headings disappear earlier than the viewport's top edge.

  3. activeTocLi: HTMLLIElement | null = null

    The DOM node of the currently active (highlighted) ToC item (based on user's scroll position on the page).

  4. aside: HTMLElement | undefined = undefined

    The DOM node of the outer-most aside element. This is the element that gets the toc class. Cannot be passed in as a prop, only for external access!

  5. blurParams: BlurParams | undefined = { duration: 200 }

    Parameters to pass to transition:blur from svelte/transition. Set to null or { duration: 0 } to disable blurring.

  6. breakpoint: number = 1000

    At what screen width in pixels to break from mobile to desktop styles.

  7. desktop: boolean = true

    true if current window width > breakpoint else false.

  8. flashClickedHeadingsFor: number = 1500

    How long (in milliseconds) a heading clicked in the ToC should receive a class of .toc-clicked in the main document. This can be used to help users immediately spot the heading they clicked on after the ToC scrolled it into view. Flash duration is in milliseconds. Set to 0 to disable this behavior. Style .toc-clicked however you like, though less is usually more. For example, the demo site uses

    :is(h2, h3, h4) {
      transition: 0.3s;
    }
    .toc-clicked {
      color: cornflowerblue;
    }
  9. getHeadingIds = (node: HTMLHeadingElement): string => node.id

    Function that receives each DOM node matching headingSelector and returns the string to set the URL hash to when clicking the associated ToC entry. Set to null to prevent updating the URL hash on ToC clicks if e.g. your headings don't have IDs.

  10. getHeadingLevels = (node: HTMLHeadingElement): number =>
      Number(node.nodeName[1]) // get the number from H1, H2, ...

    Function that receives each DOM node matching headingSelector and returns an integer from 1 to 6 for the ToC depth (determines indentation and font-size).

  11. getHeadingTitles = (node: HTMLHeadingElement): string =>
      node.textContent ?? ``

    Function that receives each DOM node matching headingSelector and returns the string to display in the TOC.

  12. headings: HTMLHeadingElement[] = []

    Array of DOM heading nodes currently listed and tracked by the ToC. Is bindable but mostly meant for reading, not writing. Deciding which headings to list should be left to the ToC and controlled via headingSelector.

  13. headingSelector: string = `:is(h2, h3, h4):not(.toc-exclude)`

    CSS selector that matches all headings to list in the ToC. You can try out selectors in the dev console of your live page to make sure they return what you want by passing it into [...document.querySelectorAll(headingSelector)]. The default selector :is(h2, h3, h4):not(.toc-exclude) excludes h5 and h6 headings as well as any node with a class of toc-exclude. For example <h2 class="toc-exclude">Section Title</h2> will not be listed.

  14. hide: boolean = false

    Whether to render the ToC. The reason you would use this and not wrap the component as a whole with Svelte's {#if} block is so that the script part of this component can still operate and keep track of the headings on the page, allowing conditional rendering based on the number or kinds of headings present (see PR#14). To access the headings <Toc> is currently tracking, use <Toc bind:headings />.

  15. autoHide: boolean = true

    Whether to automatically hide the ToC when it's empty, i.e. when no headings match headingSelector. If true, ToC also automatically un-hides itself when re-querying for headings (e.g. on scroll) and finding some.

  16. keepActiveTocItemInView: boolean = true

    Whether to keep the active ToC item in view when scrolling the page. Only applies to long ToCs that are too high to fit on screen. If true, the ToC container will scroll itself to keep the active item in view and centered (if possible). Requires scrollend event browser support (71% as of 2024-01-22), with Safari the only major browser lacking support.

  17. minItems: number = 0

    Completely prevent the ToC from rendering if it doesn't find at least minItems matching headings on the page. The default of 0 means the ToC will always render, even if it's empty.

  18. nav: HTMLElement | undefined = undefined

    The DOM node of the nav element. Cannot be passed in as a prop, only for external access!

  19. open: boolean = false

    Whether the ToC is currently in an open state on mobile screens. Can be used to externally control the open state through 2-way binding. This value is ignored on desktop.

  20. openButtonLabel: string = `Open table of contents`

    What to use as ARIA label for the button shown on mobile screens to open the ToC. Not used on desktop screens.

  21. pageBody: string | HTMLElement = `body`

    Which DOM node to use as the MutationObserver root node. This is usually the page's <main> tag or <body> element. All headings to list in the ToC should be children of this root node. Use the closest parent node containing all headings for efficiency, especially if you have a lot of elements on the page that are on a separate branch of the DOM tree from the headings you want to list.

  22. reactToKeys: string[] = [`ArrowDown`, `ArrowUp`, ` `, `Enter`, `Escape`, `Tab`]

    Which keyboard events to listen for. The default set of keys closes the ToC on Escape and Tab out, navigates the ToC list with ArrowDown, ArrowUp, and scrolls to the active ToC item on Space, and Enter. Set reactToKeys = false or [] to disable keyboard support entirely. Remove individual keys from the array to disable specific behaviors.

  23. scrollBehavior: 'auto' | 'smooth' = `smooth`

    Whether to scroll the page smoothly or instantly when clicking on a ToC item. Set to 'auto' to use the browser's default behavior.

  24. title: string = `On this page`

    ToC title to display above the list of headings. Set title='' to hide.

  25. titleTag: string = `h2`

    Change the HTML tag to be used for the ToC title. For example, to get <strong>{title}</strong>, set titleTag='strong'.

  26. tocItems: HTMLLIElement[] = []

    Array of rendered Toc list items DOM nodes. Essentially the result of document.querySelectorAll(headingSelector). Can be useful for binding.

  27. warnOnEmpty: boolean = true

    Whether to issue a console warning if the ToC is empty.

To control how far from the viewport top headings come to rest when scrolled into view from clicking on them in the ToC, use

/* replace next line with appropriate CSS selector for all your headings */
:where(h1, h2, h3, h4) {
  scroll-margin-top: 50px;
}

🎰   Slots

Toc.svelte has 3 named slots:

  • slot="toc-item" to customize how individual headings are rendered inside the ToC. It has access to the DOM node it represents via let:heading as well as the list index let:idx (counting from 0) at which it appears in the ToC.

    <Toc>
      <span let:idx let:heading slot="toc-item">
        {idx + 1}. {heading.innerText}
      </span>
    </Toc>
  • slot="title": Title shown above the list of ToC entries. Props title and titleTag have no effect when filling this slot.

  • slot="open-toc-icon": Icon shown on mobile screens which opens the ToC on clicks.

✨   Styling

The HTML structure of this component is

<aside>
  <button>open/close (only present on mobile)</button>
  <nav>
    <h2>{title}</h2>
    <ol>
      <li>{heading1}</li>
      <li>{heading2}</li>
      ...
    </ol>
  </nav>
</aside>

Toc.svelte offers the following CSS variables which can be passed in directly as props:

  • aside.toc
    • z-index: var(--toc-z-index, 1): Applies on both mobile and desktop.
  • aside.toc > nav
    • overflow: var(--toc-overflow, auto)
    • min-width: var(--toc-min-width)
    • max-width: var(--toc-desktop-max-width)
    • width: var(--toc-width)
    • max-height: var(--toc-max-height, 90vh): Height beyond which ToC will use scrolling instead of growing vertically.
    • padding: var(--toc-padding, 1em 1em 0)
    • font-size: var(--toc-font-size)
  • aside.toc > nav > ol > .toc-title
    • padding: var(--toc-title-padding)
    • margin: var(--toc-title-margin)
  • aside.toc > nav > ol
    • list-style: var(--toc-ol-list-style, none)
    • padding: var(--toc-ol-padding, 0)
    • margin: var(--toc-ol-margin)
  • aside.toc > nav > ol > li
    • border-radius: var(--toc-li-border-radius)
    • padding: var(--toc-li-padding, 2pt 4pt)
    • margin: var(--toc-li-margin)
    • border: var(--toc-li-border)
    • color: var(--toc-li-color)
  • aside.toc > nav > ol > li:hover
    • color: var(--toc-li-hover-color, cornflowerblue): Text color of hovered headings.
    • background: var(--toc-li-hover-bg)
  • aside.toc > nav > ol > li.active
    • color: var(--toc-active-color, white): Text color of the currently active heading (the one nearest but above top side of current viewport scroll position).
    • background: var(--toc-active-bg, cornflowerblue)
    • font-weight: var(--toc-active-font-weight)
    • border: var(--toc-active-border)
    • border-width: var(--toc-active-border-width): Allows setting top, right, bottom, left border widths separately.
    • border-radius: var(--toc-active-border-radius, 2pt)
  • aside.toc > button
    • color: var(--toc-mobile-btn-color, black): Menu icon color of button used as ToC opener on mobile.
    • background: var(--toc-mobile-btn-bg, rgba(255, 255, 255, 0.2)): Background of padding area around the menu icon button.
    • padding: var(--toc-mobile-btn-padding, 2pt 3pt)
    • border-radius: var(--toc-mobile-btn-border-radius, 4pt)
  • aside.toc.mobile
    • bottom: var(--toc-mobile-bottom, 1em)
    • right: var(--toc-mobile-right, 1em)
  • aside.toc.mobile > nav
    • width: var(--toc-mobile-width, 18em)
    • background: var(--toc-mobile-bg, white): Background color of the nav element hovering in the lower-left screen corner when the ToC was opened on mobile screens.
    • box-shadow: var(--toc-mobile-shadow)
    • border: var(--toc-mobile-border)
  • aside.toc.desktop
    • margin: var(--toc-desktop-aside-margin): Margin of the outer-most aside.toc element on desktops.
  • aside.toc.desktop > nav
    • margin: var(--toc-desktop-nav-margin)
    • top: var(--toc-desktop-sticky-top, 2em): How far below the screen's top edge the ToC starts being sticky.
    • background: var(--toc-desktop-bg)

Example:

<Toc
  --toc-desktop-aside-margin="10em 0 0 0"
  --toc-desktop-sticky-top="3em"
  --toc-desktop-width="15em"
/>

🧪   Coverage

Statements Branches Lines
Statements Branches Lines

🆕   Changelog

View the changelog.

🙏   Contributing

Here are some steps to get you started if you'd like to contribute to this project!

svelte-toc's People

Contributors

amerlander avatar comefled avatar janosh avatar oskar-gmerek avatar pre-commit-ci[bot] avatar roualdes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

svelte-toc's Issues

SvelteKit page navigation breaks when svelte-toc is shown

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:

  • open the Zelda post (the first one). It will load the TOC correctly (it should!)
  • scroll down the page and click on the "Conditional Hover Styles" post. It will also load the TOC, but, for that post, showToc is false. Note that, when the variable is printed, it still says true, which means nothing inside that #if block was updated.
    • I thought it was a Svelte issue at first, but if you remove the use of the TOC component, the variable updates correctly.
    • refreshing the page makes TOC go away and loads everything correctly
  • if you are in a post with TOC enabled and try going to another page (like home or Blog), navigation breaks as well

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!

New prop for toc nav overflow-y

First off, thanks for this great package.

I'm interested, though still learning Svelte (and CSS), in adding a prop for the following style

:where(aside.toc > nav) {
overflow-y: scroll;
overscroll-behavior: contain;
max-height: var(--toc-max-height, 90vh);
padding: var(--toc-padding, 1em 1em 0);
}

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.

Getting error about resolving `$app/stores`

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

Strange behaviour

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

Issues with highlighting the correct content

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.

How to use intersection observer for highlighting active heading

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!

Quick questions

Is it possible to:

  • Ye Old Pagination preferably with sort-able header column
  • "Expand" a row upon click any row
  • Nest a table "component" within an "expanded" row
  • Specific row styling upon predicate (on data load, since I'm pre-processing my data)
  • Override all possible styles

Prevents scroll when using smart zoom on macOS

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.

Nagranie.z.ekranu.2022-09-13.o.10.05.36.mov

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.

[Question] Split into sections

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:

  • find all headers
  • wrap all headers with a starting HTML <tag>
  • before starting a new tag check if is not already open, and if is - put </tag> before
  • still have no idea how find out how to close the last section

Svelte-toc interferes with other anchor links in the document

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.

Hide when intersecting with user-specified DOM nodes

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.

How do I customize the font-size of each item of the ToC?

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>

Component persisting on page change when not required

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.

Recording:
ezgif com-gif-maker

I have included my component like this

Any thoughts on why this might be happening?

[Question]TypeScript support

Hi, does this library support TypeScript?

I am getting errors when I import this library in my TypeScript project.

Component insists on starting at full height above the text

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.

wnzXSlr

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!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.