Skip to content

Commit 01bbc5c

Browse files
authored
feat(settings): redesign settings UI and localize help text (#1933)
1 parent cc7c385 commit 01bbc5c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+8654
-752
lines changed

src/components/searchbar/index.js

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
4949

5050
function hide() {
5151
actionStack.remove("searchbar");
52-
53-
if (!$list.parentElement) return;
5452
if (typeof onhideCb === "function") onhideCb();
5553

5654
$list.content = children;
@@ -70,6 +68,12 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
7068
*/
7169
async function searchNow() {
7270
const val = $searchInput.value.toLowerCase();
71+
72+
if (!val) {
73+
$list.content = children;
74+
return;
75+
}
76+
7377
let result;
7478

7579
if (searchFunction) {
@@ -89,7 +93,7 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
8993
}
9094

9195
$list.textContent = "";
92-
$list.append(...result);
96+
$list.append(...buildSearchContent(result, val));
9397
}
9498

9599
/**
@@ -103,6 +107,87 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
103107
return text.match(val, "i");
104108
});
105109
}
110+
111+
/**
112+
* Keep grouped settings search results in section cards instead of flattening them.
113+
* @param {HTMLElement[]} result
114+
* @param {string} val
115+
* @returns {HTMLElement[]}
116+
*/
117+
function buildSearchContent(result, val) {
118+
if (!val || !result.length) return result;
119+
120+
const groupedSections = [];
121+
const sectionIndexByLabel = new Map();
122+
let hasGroups = false;
123+
124+
result.forEach(($item) => {
125+
const label = $item.dataset.searchGroup;
126+
if (!label) {
127+
groupedSections.push({
128+
items: [$item],
129+
type: "ungrouped",
130+
});
131+
return;
132+
}
133+
134+
hasGroups = true;
135+
const existingSectionIndex = sectionIndexByLabel.get(label);
136+
if (existingSectionIndex !== undefined) {
137+
groupedSections[existingSectionIndex].items.push($item);
138+
return;
139+
}
140+
141+
sectionIndexByLabel.set(label, groupedSections.length);
142+
groupedSections.push({
143+
items: [$item],
144+
label,
145+
type: "group",
146+
});
147+
});
148+
149+
if (!hasGroups) return result.map(cloneSearchItem);
150+
151+
const countLabel = `${result.length} ${
152+
result.length === 1
153+
? strings["search result label singular"]
154+
: strings["search result label plural"]
155+
}`;
156+
const content = [
157+
<div className="settings-search-summary">{countLabel}</div>,
158+
];
159+
160+
groupedSections.forEach((section) => {
161+
if (section.type === "ungrouped") {
162+
content.push(...section.items.map(cloneSearchItem));
163+
return;
164+
}
165+
166+
content.push(
167+
<section className="settings-section settings-search-section">
168+
<div className="settings-section-label">{section.label}</div>
169+
<div className="settings-section-card">
170+
{section.items.map(cloneSearchItem)}
171+
</div>
172+
</section>,
173+
);
174+
});
175+
176+
return content;
177+
}
178+
179+
/**
180+
* Render search results without moving the original list items out of their groups.
181+
* @param {HTMLElement} $item
182+
* @returns {HTMLElement}
183+
*/
184+
function cloneSearchItem($item) {
185+
const $clone = $item.cloneNode(true);
186+
$clone.addEventListener("click", () => {
187+
$item.click();
188+
});
189+
return $clone;
190+
}
106191
}
107192

108193
export default searchBar;

0 commit comments

Comments
 (0)