@codedoc/core
Version:
Create beautiful modern documentation websites.
142 lines • 6.3 kB
JavaScript
import { state, pipe, pin, map, pack, emission, filter, sink } from '@connectv/core';
import { debounceTime, startWith, share } from 'rxjs/operators';
import { ref, List } from '@connectv/html';
import { ToCSearchOverlayStyle } from './style';
import { Loading } from '../../../../util/loading';
import { getConfig } from '../../../../../transport/config';
export function ToCSearchOverlay(options, renderer) {
const classes = this.theme.classes(ToCSearchOverlayStyle);
const holder = ref();
const input = ref();
const toc = ref();
const findFocus = () => {
let focused = undefined;
let prev = undefined;
let next = undefined;
let first = undefined;
let last = undefined;
holder.$.querySelectorAll('a[tabindex]').forEach(a$ => {
if (!first)
first = a$;
if (a$ === document.activeElement)
focused = a$;
else {
if (!focused)
prev = a$;
else if (!next)
next = a$;
}
last = a$;
});
const res = {};
res.next = next || first;
res.prev = prev || last;
return res;
};
this.track({
bind() {
input.$.focus();
holder.$.classList.add('active');
toc.resolve(document.getElementById('-codedoc-toc') || renderer.create("fragment", null));
if (!('backdropFilter' in holder.$.style) && !('-webkit-backdrop-filter' in holder.$.style)) {
holder.$.style.background = 'rgba(64, 64, 64, .95)';
}
}
});
const query = state(localStorage.getItem('-codedoc-search-query') || '');
const loading = state(false);
const queryOut = this.expose.out('query');
const results = this.expose.in('results', pin())
.to(pipe(share()))
.to(map((links) => {
const res = links.map(l => {
const conf = getConfig();
if (conf)
l = conf.namespace + l;
return { link: l, title: tocLinkTitle(l) };
});
if (query.value.length > 0) {
toc.$.querySelectorAll('a').forEach(a$ => {
var _a;
if (((_a = a$.textContent) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(query.value.toLowerCase())) && a$.getAttribute('href')
&& !links.includes(a$.getAttribute('href') || ''))
res.push({ link: a$.getAttribute('href') || '',
title: a$.textContent });
});
}
return res;
}))
.to(sink(res => {
if (res.length > 0) {
localStorage.setItem('-codedoc-search-query', query.value);
localStorage.setItem('-codedoc-search-res', JSON.stringify(res));
}
}))
.to(pipe(startWith(emission(JSON.parse(localStorage.getItem('-codedoc-search-res') || '[]')))));
query
.to(filter((q) => q && q.trim().length > 0))
.to(loading.from(map(() => true)), queryOut.from(pipe(debounceTime(1000))));
results.to(map(() => false)).to(loading);
const hideEmpty = pack(query, results, loading)
.to(map(([_query, _results, _loading]) => {
if (_loading)
return true;
else
return !_query || _query.trim().length == 0 || _results.length > 0;
}));
const tocLinkTitle = (link) => { var _a; return ((_a = toc.$.querySelector(`a[href="${link}"]`)) === null || _a === void 0 ? void 0 : _a.textContent) || link; };
const close = (clean = true) => {
holder.$.remove();
if (clean) {
localStorage.removeItem('-codedoc-search-query');
}
};
return renderer.create("div", { class: classes.overlay, _ref: holder, onkeydown: event => {
const key = event.key;
if (key === 'Escape') {
event.preventDefault();
event.stopPropagation();
close();
}
if (key === 'ArrowDown') {
const focus = findFocus();
if (focus.next) {
focus.next.focus();
event.preventDefault();
event.stopPropagation();
}
}
if (key === 'ArrowUp') {
const focus = findFocus();
if (focus.prev) {
focus.prev.focus();
event.preventDefault();
event.stopPropagation();
}
}
if (key === 'ArrowLeft' || key === 'ArrowRight')
event.stopPropagation();
} },
renderer.create("div", { class: classes.content },
renderer.create("div", { class: "top" },
renderer.create("input", { placeholder: options.placeholder, type: "text", _ref: input, _state: query }),
renderer.create("div", { class: classes.close, onclick: () => {
if (query.value.length > 0)
query.value = '';
else
close();
} })),
renderer.create("div", { class: classes.results },
renderer.create("div", { class: "loading", hidden: loading.to(map((_) => !_)) },
renderer.create(Loading, null)),
renderer.create("div", { class: "empty", hidden: hideEmpty }, "No Results!"),
renderer.create("div", { hidden: loading },
renderer.create(List, { of: results, each: result => renderer.create("a", { href: result.sub('link'), tabindex: "0", onclick: () => {
close(false);
window.dispatchEvent(new CustomEvent('on-navigation-search', { detail: { query: query.value } }));
} },
renderer.create("span", { class: "title" }, result.sub('title')),
renderer.create("span", { class: "current", hidden: result.sub('link').to(map((l) => l !== location.pathname)) }, "Search on Current Page")) })))));
}
export { ToCSearchOverlayStyle } from './style';
//# sourceMappingURL=index.js.map