сворачивание / разворачивание элементов дерева при поиске
This commit is contained in:
parent
45fedcd359
commit
c187c66737
10
index.html
10
index.html
@ -105,11 +105,19 @@
|
|||||||
<label class="toggle-row">
|
<label class="toggle-row">
|
||||||
<span>
|
<span>
|
||||||
<strong>Показывать теги дерева</strong>
|
<strong>Показывать теги дерева</strong>
|
||||||
<small>Тип сервиса рядом с элементом</small>
|
<small>Поисковые теги рядом с элементом</small>
|
||||||
</span>
|
</span>
|
||||||
<input type="checkbox" data-show-tree-tags />
|
<input type="checkbox" data-show-tree-tags />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="toggle-row">
|
||||||
|
<span>
|
||||||
|
<strong>Авто раскрывать поиск</strong>
|
||||||
|
<small>Сворачивать ветки без совпадений</small>
|
||||||
|
</span>
|
||||||
|
<input type="checkbox" data-auto-collapse-search />
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="control-group accent-group">
|
<div class="control-group accent-group">
|
||||||
<span>Акцент</span>
|
<span>Акцент</span>
|
||||||
<button
|
<button
|
||||||
|
|||||||
37
script.js
37
script.js
@ -139,6 +139,7 @@ const defaultPreferences = {
|
|||||||
accent: "violet",
|
accent: "violet",
|
||||||
showNumbers: false,
|
showNumbers: false,
|
||||||
showTreeTags: true,
|
showTreeTags: true,
|
||||||
|
autoCollapseSearch: true,
|
||||||
sidebarWidth: 390,
|
sidebarWidth: 390,
|
||||||
};
|
};
|
||||||
const availableViews = ["cards", "list", "compact-cards", "compact-list"];
|
const availableViews = ["cards", "list", "compact-cards", "compact-list"];
|
||||||
@ -158,6 +159,7 @@ const viewButtons = document.querySelectorAll("[data-view]");
|
|||||||
const accentButtons = document.querySelectorAll("[data-accent]");
|
const accentButtons = document.querySelectorAll("[data-accent]");
|
||||||
const showNumbersInput = document.querySelector("[data-show-numbers]");
|
const showNumbersInput = document.querySelector("[data-show-numbers]");
|
||||||
const showTreeTagsInput = document.querySelector("[data-show-tree-tags]");
|
const showTreeTagsInput = document.querySelector("[data-show-tree-tags]");
|
||||||
|
const autoCollapseSearchInput = document.querySelector("[data-auto-collapse-search]");
|
||||||
const emptyTemplate = document.querySelector("#empty-template");
|
const emptyTemplate = document.querySelector("#empty-template");
|
||||||
|
|
||||||
renderNavigationTree();
|
renderNavigationTree();
|
||||||
@ -247,6 +249,13 @@ showTreeTagsInput.addEventListener("change", () => {
|
|||||||
savePreferences(preferences);
|
savePreferences(preferences);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
autoCollapseSearchInput.addEventListener("change", () => {
|
||||||
|
preferences.autoCollapseSearch = autoCollapseSearchInput.checked;
|
||||||
|
applyPreferences(preferences);
|
||||||
|
renderNavigationTree();
|
||||||
|
savePreferences(preferences);
|
||||||
|
});
|
||||||
|
|
||||||
sidebarResizer.addEventListener("pointerdown", (event) => {
|
sidebarResizer.addEventListener("pointerdown", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.body.classList.add("is-resizing-sidebar");
|
document.body.classList.add("is-resizing-sidebar");
|
||||||
@ -423,15 +432,37 @@ function matchesQuery(item, group, section, query) {
|
|||||||
return haystack.includes(query);
|
return haystack.includes(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function groupMatchesQuery(group, section, query) {
|
||||||
|
if (!query) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
matchesText([group.number, group.title, group.description, section.title], query) ||
|
||||||
|
group.items.some((item) => matchesQuery(item, group, section, query))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesText(values, query) {
|
||||||
|
if (!query) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalize(values.join(" ")).includes(query);
|
||||||
|
}
|
||||||
|
|
||||||
function renderNavigationTree() {
|
function renderNavigationTree() {
|
||||||
const query = normalize(searchInput.value);
|
const query = normalize(searchInput.value);
|
||||||
|
const shouldAutoCollapse = Boolean(query && preferences.autoCollapseSearch);
|
||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
|
|
||||||
ecosystemSections.forEach((section) => {
|
ecosystemSections.forEach((section) => {
|
||||||
|
const sectionOwnMatch = matchesText([section.number, section.title, section.description], query);
|
||||||
|
const sectionHasMatches = sectionOwnMatch || section.groups.some((group) => groupMatchesQuery(group, section, query));
|
||||||
const sectionNode = document.createElement("details");
|
const sectionNode = document.createElement("details");
|
||||||
sectionNode.className = "tree-section";
|
sectionNode.className = "tree-section";
|
||||||
sectionNode.dataset.collapseKey = getTreeSectionId(section);
|
sectionNode.dataset.collapseKey = getTreeSectionId(section);
|
||||||
sectionNode.open = getSavedOpenState(sectionNode.dataset.collapseKey);
|
sectionNode.open = shouldAutoCollapse ? sectionHasMatches : getSavedOpenState(sectionNode.dataset.collapseKey);
|
||||||
|
|
||||||
const sectionSummary = document.createElement("summary");
|
const sectionSummary = document.createElement("summary");
|
||||||
sectionSummary.innerHTML = `
|
sectionSummary.innerHTML = `
|
||||||
@ -443,10 +474,11 @@ function renderNavigationTree() {
|
|||||||
sectionNode.append(sectionSummary);
|
sectionNode.append(sectionSummary);
|
||||||
|
|
||||||
section.groups.forEach((group) => {
|
section.groups.forEach((group) => {
|
||||||
|
const groupHasMatches = groupMatchesQuery(group, section, query);
|
||||||
const groupNode = document.createElement("details");
|
const groupNode = document.createElement("details");
|
||||||
groupNode.className = "tree-group";
|
groupNode.className = "tree-group";
|
||||||
groupNode.dataset.collapseKey = getTreeGroupId(group);
|
groupNode.dataset.collapseKey = getTreeGroupId(group);
|
||||||
groupNode.open = getSavedOpenState(groupNode.dataset.collapseKey);
|
groupNode.open = shouldAutoCollapse ? groupHasMatches : getSavedOpenState(groupNode.dataset.collapseKey);
|
||||||
|
|
||||||
const groupSummary = document.createElement("summary");
|
const groupSummary = document.createElement("summary");
|
||||||
groupSummary.innerHTML = `
|
groupSummary.innerHTML = `
|
||||||
@ -576,6 +608,7 @@ function applyPreferences(nextPreferences) {
|
|||||||
document.documentElement.dataset.showTreeTags = String(Boolean(nextPreferences.showTreeTags));
|
document.documentElement.dataset.showTreeTags = String(Boolean(nextPreferences.showTreeTags));
|
||||||
showNumbersInput.checked = Boolean(nextPreferences.showNumbers);
|
showNumbersInput.checked = Boolean(nextPreferences.showNumbers);
|
||||||
showTreeTagsInput.checked = Boolean(nextPreferences.showTreeTags);
|
showTreeTagsInput.checked = Boolean(nextPreferences.showTreeTags);
|
||||||
|
autoCollapseSearchInput.checked = Boolean(nextPreferences.autoCollapseSearch);
|
||||||
setActiveButton(themeButtons, "theme", nextPreferences.theme);
|
setActiveButton(themeButtons, "theme", nextPreferences.theme);
|
||||||
setActiveButton(viewButtons, "view", nextPreferences.view);
|
setActiveButton(viewButtons, "view", nextPreferences.view);
|
||||||
setActiveButton(accentButtons, "accent", nextPreferences.accent);
|
setActiveButton(accentButtons, "accent", nextPreferences.accent);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user