diff --git a/.eslintrc b/.eslintrc index c31d933..ee963ca 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,8 @@ "browser": true }, "globals": { - "gtag": false + "gtag": false, + "tocbot": false }, "parserOptions": { "ecmaVersion": 10, diff --git a/assets/js/table-of-contents.js b/assets/js/table-of-contents.js new file mode 100644 index 0000000..1182f2c --- /dev/null +++ b/assets/js/table-of-contents.js @@ -0,0 +1,38 @@ +const TOC_ID = 'obsah'; + +const generateToc = () => { + tocbot.init({ + activeLinkClass: 'is-active', + collapsibleClass: 'is-collapsible', + contentSelector: '.js-table-of-contents-source', + headingSelector: 'h1, h2, h3', + isCollapsedClass: 'is-collapsed', + linkClass: 'table-of-contents__link', + listClass: 'table-of-contents__list', + listItemClass: 'table-of-contents__list__item', + scrollSmooth: false, + tocSelector: `#${TOC_ID}`, + }); + + document.getElementById(TOC_ID).classList.add('table-of-contents--active'); +}; + +const destroyToc = () => { + document.getElementById(TOC_ID).classList.remove('table-of-contents--active'); + tocbot.destroy(); +}; + +const updateToc = () => { + const tocEl = document.getElementById(TOC_ID); + + if (window.getComputedStyle(tocEl).display !== 'none') { + if (!tocEl.innerHTML) { + generateToc(); + } + } else if (tocEl.innerHTML) { + destroyToc(); + } +}; + +window.addEventListener('load', () => updateToc()); +window.addEventListener('resize', () => updateToc()); diff --git a/assets/scss/main.scss b/assets/scss/main.scss index 7957943..55a9141 100644 --- a/assets/scss/main.scss +++ b/assets/scss/main.scss @@ -52,6 +52,7 @@ @use 'styles/04-components/navigation'; @use 'styles/04-components/post-card'; @use 'styles/04-components/share'; +@use 'styles/04-components/table-of-contents'; @use 'styles/04-components/text-field'; // 5. Editor diff --git a/assets/scss/styles/04-components/_table-of-contents.scss b/assets/scss/styles/04-components/_table-of-contents.scss new file mode 100644 index 0000000..565153e --- /dev/null +++ b/assets/scss/styles/04-components/_table-of-contents.scss @@ -0,0 +1,44 @@ +@use '../../settings/container'; +@use '../../tools/breakpoint'; +@use '../../tools/spacing'; +@use '../../tools/transition'; +@use '../../tools/typography'; + +$_breakpoint: xl; + +.table-of-contents { + display: none; + + @include breakpoint.up($_breakpoint) { + @include transition.add('visibility, opacity'); + + position: sticky; + top: 0; + right: 0; + display: block; + visibility: hidden; + opacity: 0; + width: calc((100vw - #{container.$article-width}) / 2); + height: 0; + padding: spacing.of(2) container.$padding-sm; + line-height: typography.line-height(dense); + will-change: visibility, opacity; + } +} + +.table-of-contents__list { + @include breakpoint.up($_breakpoint) { + @include typography.style(small); + } +} + +.table-of-contents__list .table-of-contents__list { + font-size: inherit; +} + +.table-of-contents--active { + @include breakpoint.up($_breakpoint) { + visibility: visible; + opacity: 1; + } +} diff --git a/post.hbs b/post.hbs index 4df203c..505dbd6 100644 --- a/post.hbs +++ b/post.hbs @@ -80,10 +80,16 @@ + {{^has tag="galerie"}} +
{{!-- TOC holder for `position: sticky` --}} + +
+ {{/has}} +
-