UNPKG

relift-html

Version:

A blazing fast view library that lets you put Javascript Template Literals in HTML

314 lines (276 loc) 8.4 kB
--- title: Guide description: reLift-HTML guide. docs: - introduction.md - syntax.md - installation.md - component.md - lifecycle.md - data.md - props.md - methods.md - directives.md - events.md - shared-state.md --- <template> <div class="wrapper"> <header class="header header-dark"> <div class="container" id="guide-header"> <h2 class="title">GUIDE</h2> </div> </header> <div class="container"> <div class="row"> <div class="column column-25"> <div id="sideMenu" style="display:none"> <div id="menu-toggler" @call="toggleMenuToggler"> <i class="fas fa-bars"></i> </div> <div id="content-side-affix" class="top"> <ul class="side-nav"> <li r-for="item in this.menu" data-section="${item.url}"> <a href="#${item.url}" data-affix-link="#${item.url}">${item.title}</a> <ul> <li r-for="sitem in item.subsections"><a href="#${sitem.url}" data-affix-link="#${sitem.url}">${sitem.title}</a></li> </ul> </li> </ul> <div><a href="#" @call="scrollToTop">Back to top</a></div> <hr> <a href="https://github.com/mardix/relift-html/tree/master/docs" target="_blank">Edit on Github</a> </div> </div> </div> <div class="column guides" id="page-guide"> {% for doc in page.docs %} <section class="doc" data-doc="{{ doc }}"> {% include 'content/guide-docs/%s' % doc %} </section> <hr> {% endfor %} </div> </div> </div> </div> </template> <style scss> #page-guide { margin-bottom: 40px; h2 { display: block; border-bottom: 1px solid #312450; margin-bottom: 40px; padding-bottom: 10px; font-size: 4.0rem; color: #312450; } h3 { border-top: 1px dotted #ccc; padding-top: 10px; padding-bottom: 10px; font-size: 2.5rem } } #menu-toggler { display: none; } #content-side-affix { position: relative; top: 0px; &.lock { top: 100px; width: 200px; position: fixed; } } @media (min-width: 320px) and (max-width: 639px) { #menu-toggler { .fas { font-size: 25px; color: #312450; font-weight: bold; }; text-align: center; background: #fff; padding: 10px; left: -20px; top: 70px; height: 50px; width: 85px; position: fixed; z-index: 100; display: block; border: 1px solid #312450; border-radius: 60px; } #content-side-affix { background: #fff; height: 100%; position: fixed; width: 110%; margin-left: 0px; left: -10px; text-align: center; top: 190px; padding-top: 60px; display: none; &.show { display: block; } ul { li { margin-bottom: 20px; a { font-size: 24px; } ul { } } } &.top { top: 0px; } } } ul { &.side-nav { list-style: none; li { a { color: #312450; font-size: 20px; } ul { list-style: none; margin-left: 10px; margin-top: 5px; display: none; li { margin-top: 5px; a { font-size: 14px; color: #606c76; } } } &.active { ul { display: block; } } } } } </style> <script type="module"> import reLiftHTML from '//unpkg.com/relift-html'; const debounce = (callback, time = 250, interval) => (...args) => clearTimeout(interval, interval = setTimeout(callback, time, ...args)); reLiftHTML({ el: '#sideMenu', isShadow: false, data: { menu: [] }, created() { const sections = []; const scrollSpies = {}; for (const s of document.querySelectorAll('#page-guide section')) { const h2 = s.querySelector('h2'); h2.parentElement.setAttribute('data-section', h2.id); const slug = this.slugify(h2.innerText); h2.setAttribute('id', `${slug}`) scrollSpies[slug] = h2.offsetTop; /** Fix the anchoring problem with all the MDs It will remap href and if; **/ s.querySelectorAll('.toc ul li a').forEach(el => { const href = el.getAttribute('href').replace('#', ''); if (slug !== href) { const id = `${slug}__${href}`; el.setAttribute('href', `#${id}`); el.addEventListener('click', e => { e.preventDefault(); this.scrollTo(document.querySelector(`#${id}`)); }) } }) s.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(el => { const id = el.getAttribute('id'); if (id && id !== slug) { el.setAttribute('id', `${slug}__${id}`) } }) sections.push({ title: h2.innerText, url: slug, subsections: [...s.querySelectorAll('h3')].map(el => { const id = el.getAttribute('id'); return { title: el.innerText, url: `${id}` } }) }) } this.data.menu = sections; //this.data.scrollSpies = scrollSpies; const scrollSpy = debounce(() => { const scrollPosition = document.documentElement.scrollTop || document.body.scrollTop; for (const i in scrollSpies) { if (scrollSpies[i] <= scrollPosition) { const lastActive = this.el.querySelector('ul li.active'); const active = this.el.querySelector(`[data-section="${i}"]`); if (lastActive) lastActive.classList.remove('active'); if (active) active.classList.add('active'); } } }, 100); const el = this.el.querySelector('#content-side-affix') const top = el.getAttribute('data-affix-top') || 100; const scroll = () => { const scrollTop = window.pageYOffset; const contentSideAffix = this.el.querySelector('#content-side-affix'); if (window.matchMedia('(min-width: 640px)').matches) { if( scrollTop > 100 ){ contentSideAffix.classList.add('lock'); } else { contentSideAffix.classList.remove('lock');; } contentSideAffix.classList.remove('show') scrollSpy(); } else { } }; [...el.querySelectorAll('[data-affix-link]')].map(e => { e.addEventListener('click', (ev) => { ev.preventDefault(); this.scrollTo(document.querySelector(e.getAttribute('data-affix-link'))); setTimeout(() => { scroll(); }, 300) }) }) window.onscroll = scroll; }, slugify: (s) => { return s.toLowerCase() .replace(/[^\w\s-]/g, '') // remove non-word [a-z0-9_], non-whitespace, non-hyphen characters .replace(/[\s_-]+/g, '-') // swap any length of whitespace, underscore, hyphen characters with a single - .replace(/^-+|-+$/g, '') // remove leading, trailing - }, scrollTo(el){ history.replaceState(undefined, undefined,`#${el.id}`); el.scrollIntoView({behavior: "smooth"}); this.el.querySelector('#content-side-affix').classList.remove('show') }, scrollToTop() { this.scrollTo(document.querySelector('#guide-header')); }, toggleMenuToggler() { this.el.querySelector('#content-side-affix').classList.toggle('show') } }); </script>