forked from Acode-Foundation/Acode
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
108 lines (93 loc) · 2.25 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import "./style.scss";
import Ref from "html-tag-js/ref";
import actionStack from "lib/actionStack";
/**
* Create and activate search bar
* @param {HTMLUListElement|HTMLOListElement} $list
* @param {(hide:Function)=>void} setHide
* @param {()=>void} onhideCb callback to be called when search bar is hidden
* @param {(value:string)=>HTMLElement[]} searchFunction
*/
function searchBar($list, setHide, onhideCb, searchFunction) {
let hideOnBlur = true;
let timeout = null;
const $searchInput = new Ref();
/**@type {HTMLDivElement} */
const $container = (
<div id="search-bar">
<input
ref={$searchInput}
type="search"
placeholder={strings.search}
enterKeyHint="go"
/>
<span className="icon clearclose" onclick={hide}></span>
</div>
);
/**@type {HTMLElement[]} */
const children = [...$list.children];
if (typeof setHide === "function") {
hideOnBlur = false;
setHide(hide);
}
app.appendChild($container);
$searchInput.el.oninput = search;
$searchInput.el.focus();
$searchInput.el.onblur = () => {
if (!hideOnBlur) return;
setTimeout(hide, 0);
};
actionStack.push({
id: "searchbar",
action: hide,
});
function hide() {
actionStack.remove("searchbar");
if (!$list.parentElement) return;
if (typeof onhideCb === "function") onhideCb();
$list.content = children;
$container.classList.add("hide");
setTimeout(() => {
$container.remove();
}, 300);
}
function search() {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(searchNow.bind(this), 500);
}
/**
* @this {HTMLInputElement}
*/
async function searchNow() {
const val = $searchInput.value.toLowerCase();
let result;
if (searchFunction) {
result = searchFunction(val);
if (result instanceof Promise) {
try {
result = await result;
} catch (error) {
window.log("error", "Search function failed:");
window.log("error", error);
result = [];
}
}
} else {
result = filterList(val);
}
$list.textContent = "";
$list.append(...result);
}
/**
* Search list items
* @param {string} val
* @returns
*/
function filterList(val) {
return children.filter((child) => {
const text = child.textContent.toLowerCase();
return text.match(val, "i");
});
}
}
export default searchBar;