UNPKG

@codedoc/core

Version:

Create beautiful modern documentation websites.

142 lines 6.3 kB
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