@nuxt/ui
Version:
A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.
64 lines (63 loc) • 1.88 kB
JavaScript
function truncateHTMLFromStart(html, maxLength) {
let truncated = "";
let totalLength = 0;
let insideTag = false;
for (let i = html.length - 1; i >= 0; i--) {
if (html[i] === ">") {
insideTag = true;
} else if (html[i] === "<") {
insideTag = false;
truncated = html[i] + truncated;
continue;
}
if (!insideTag) {
totalLength++;
}
if (totalLength <= maxLength) {
truncated = html[i] + truncated;
} else {
truncated = "..." + truncated;
break;
}
}
return truncated;
}
export function highlight(item, searchTerm, forceKey, omitKeys) {
function generateHighlightedText(value, indices = []) {
value = value || "";
let content = "";
let nextUnhighlightedRegionStartingIndex = 0;
indices.forEach((region) => {
if (region.length === 2 && region[0] === region[1]) {
return;
}
const lastIndiceNextIndex = region[1] + 1;
const isMatched = lastIndiceNextIndex - region[0] >= searchTerm.length;
content += [
value.substring(nextUnhighlightedRegionStartingIndex, region[0]),
isMatched && `<mark>`,
value.substring(region[0], lastIndiceNextIndex),
isMatched && "</mark>"
].filter(Boolean).join("");
nextUnhighlightedRegionStartingIndex = lastIndiceNextIndex;
});
content += value.substring(nextUnhighlightedRegionStartingIndex);
const markIndex = content.indexOf("<mark>");
if (markIndex !== -1) {
content = truncateHTMLFromStart(content, content.length - markIndex);
}
return content;
}
if (!item.matches?.length) {
return;
}
for (const match of item.matches) {
if (forceKey && match.key !== forceKey) {
continue;
}
if (omitKeys?.includes(match.key)) {
continue;
}
return generateHighlightedText(match.value, match.indices);
}
}