element-book
Version:
An [`element-vir`](https://npmjs.com/package/element-vir) drop-in element for building, testing, and demonstrating a collection of elements (or, in other words, a design system).
75 lines (74 loc) • 2.94 kB
JavaScript
import { check } from '@augment-vir/assert';
import { randomString } from '@augment-vir/common';
import { convertTemplateToString } from 'element-vir';
import { fuzzySearch } from '../../util/fuzzy-search.js';
const searchJoin = randomString(32);
function createBreadcrumbsSearchKey(breadcrumbs) {
return breadcrumbs.join(searchJoin);
}
function getFullTreeKeysToInclude(breadcrumbs) {
if (!breadcrumbs.length) {
return [];
}
const currentKey = createBreadcrumbsSearchKey(breadcrumbs);
const ancestorKeys = getFullTreeKeysToInclude(breadcrumbs.slice(0, -1));
return [
currentKey,
...ancestorKeys,
];
}
const errorQueries = [
'error',
'errors',
];
function isSearchingForErrors(searchQuery) {
return errorQueries.includes(searchQuery);
}
export function searchFlattenedNodes({ flattenedNodes, searchQuery, }) {
const includeInSearchResults = {};
function addChildren(treeNode) {
const childrenKeys = Object.values(treeNode.children).map((child) => {
addChildren(child);
return createBreadcrumbsSearchKey(child.fullUrlBreadcrumbs);
});
childrenKeys.forEach((keyToInclude) => (includeInSearchResults[keyToInclude] = true));
}
flattenedNodes.forEach((treeNode) => {
const matchesErrors = treeNode.entry.errors.length && isSearchingForErrors(searchQuery);
const currentNodeSearchKey = createBreadcrumbsSearchKey(treeNode.fullUrlBreadcrumbs);
const shouldInclude = fuzzySearch({
searchIn: [
treeNode.entry.title,
...treeNode.entry.descriptionParagraphs.map((paragraph) => {
if (check.isString(paragraph)) {
return paragraph;
}
else {
return convertTemplateToString(paragraph);
}
}),
]
.join(' ')
.toLowerCase(),
searchQuery: searchQuery.toLowerCase(),
}) ||
matchesErrors ||
includeInSearchResults[currentNodeSearchKey];
if (shouldInclude) {
const keysToInclude = getFullTreeKeysToInclude(treeNode.fullUrlBreadcrumbs);
addChildren(treeNode);
keysToInclude.forEach((keyToInclude) => (includeInSearchResults[keyToInclude] = true));
}
else {
includeInSearchResults[currentNodeSearchKey] = false;
}
});
return flattenedNodes.filter((treeNode) => {
const inSearchResultsKey = createBreadcrumbsSearchKey(treeNode.fullUrlBreadcrumbs);
const shouldInclude = includeInSearchResults[inSearchResultsKey];
if (!check.isBoolean(shouldInclude)) {
throw new TypeError(`Failed to find '${treeNode.fullUrlBreadcrumbs.join(' > ')}' in includeInSearchResults.`);
}
return shouldInclude;
});
}