From 4e79a4aaffc0e832125b07c8c1ce2e979746e8d8 Mon Sep 17 00:00:00 2001 From: Adam Kudrna Date: Mon, 9 Nov 2020 23:54:07 +0100 Subject: [PATCH] Add table of contents to articles (#5) --- .eslintrc | 3 +- assets/js/table-of-contents.js | 38 ++++++++++++++++ assets/scss/main.scss | 1 + .../04-components/_table-of-contents.scss | 44 +++++++++++++++++++ post.hbs | 13 +++++- 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 assets/js/table-of-contents.js create mode 100644 assets/scss/styles/04-components/_table-of-contents.scss 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..cd87a55 --- /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: 'toc__link', + listClass: 'toc__list', + listItemClass: 'toc__list__item', + scrollSmooth: false, + tocSelector: `#${TOC_ID}`, + }); + + document.getElementById(TOC_ID).classList.add('toc--active'); +}; + +const destroyToc = () => { + document.getElementById(TOC_ID).classList.remove('toc--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 ff16f00..8419a64 100644 --- a/assets/scss/main.scss +++ b/assets/scss/main.scss @@ -52,6 +52,7 @@ @import 'styles/04-components/navigation'; @import 'styles/04-components/post-card'; @import 'styles/04-components/share'; +@import 'styles/04-components/table-of-contents'; @import '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 b769d5f..0ec6276 100644 --- a/post.hbs +++ b/post.hbs @@ -76,10 +76,16 @@ + {{^has tag="galerie"}} +
+ +
+ {{/has}} +
-