relift-html
Version:
A blazing fast view library that lets you put Javascript Template Literals in HTML
314 lines (276 loc) • 8.4 kB
HTML
---
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>