@anjuna/docs
Version:
Anjuna Documentation Web Components
126 lines (125 loc) • 4.05 kB
JavaScript
import { h } from "@stencil/core";
export class Toc {
constructor() {
this.activeId = '#overview';
/**
* The object map of usa cases to their markdown
*/
this.docs = {};
/**
* The object map of usa cases to their markdown
*/
this.keys = [];
}
onDemosChange() {
this.sectionIds = ['#overview'].concat(this.keys.map(d => `#${d}`)).concat('#api');
}
async connectedCallback() {
this.navigate = debounce(this.navigate.bind(this), 100);
this.onScroll = debounce(this.onScroll.bind(this), 25);
this.onDemosChange();
if (window.location.hash) {
return this.navigate();
}
}
onScroll() {
const els = this.sectionIds.map(id => document.querySelector(id));
let closest = els[0];
els.slice(1).forEach(el => {
if (el && Math.abs(window.scrollY - el.offsetTop) < Math.abs(window.scrollY - closest.offsetTop)) {
closest = el;
}
});
this.activeId = `#${closest.getAttribute('id')}`;
}
parseTitle(id) {
const usage = id.replace('#', '');
const doc = this.docs[usage];
return doc ? doc.split(/##(.*?)\n/).find(p => p !== '').trim() : usage;
}
anchorClass(usage) {
return usage === this.activeId ? 'anj-active' : '';
}
navigate() {
return new Promise(resolve => {
window.setTimeout(() => {
this.activeId = window.location.hash;
const el = document.querySelector(this.activeId);
if (el) {
window.scrollTo(0, el.offsetTop);
}
resolve();
}, 500);
});
}
render() {
if (!this.sectionIds) {
return;
}
const path = window.location.pathname;
return (h("div", { class: "anj-toc" }, this.sectionIds.map(id => h("a", { href: `${path}${id}`, onClick: () => this.activeId = id, class: this.anchorClass(id) }, this.parseTitle(id)))));
}
static get is() { return "ad-toc"; }
static get originalStyleUrls() { return {
"$": ["toc.scss"]
}; }
static get styleUrls() { return {
"$": ["toc.css"]
}; }
static get properties() { return {
"docs": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "{[key: string]: string}",
"resolved": "{ [key: string]: string; }",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The object map of usa cases to their markdown"
},
"defaultValue": "{}"
},
"keys": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "string[]",
"resolved": "string[]",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The object map of usa cases to their markdown"
},
"defaultValue": "[]"
}
}; }
static get states() { return {
"activeId": {},
"sectionIds": {}
}; }
static get watchers() { return [{
"propName": "keys",
"methodName": "onDemosChange"
}]; }
static get listeners() { return [{
"name": "scroll",
"method": "onScroll",
"target": "window",
"capture": false,
"passive": true
}]; }
}
const debounce = (func, wait = 0) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(func, wait, ...args);
};
};