diff --git a/design/Core.css b/design/Core.css
index 2912f63..8dd20dd 100644
--- a/design/Core.css
+++ b/design/Core.css
@@ -3,7 +3,7 @@
*/
:root {
--disabled-color: rgb(94, 109, 120);
-
+
--main-font: Lato, "Helvetica Nueue", Helvetica, Arial, sans-serif;
--title-font: Means, Georgia, serif;
@@ -34,7 +34,7 @@ body {
--input-color: rgb(189, 189, 189);
--lighter-color: rgba(132, 139, 200, 0.09);
--light-color: rgba(132, 139, 200, 0.18);
- --dark-color: rgba(132, 139, 200, 0.24);
+ --dark-color: rgba(132, 139, 200, 0.24);
--border-color: rgba(132, 139, 200, 0.18);
}
.dark-mode {
diff --git a/design/Dialog.css b/design/Dialog.css
index 6d7d670..54d54a7 100644
--- a/design/Dialog.css
+++ b/design/Dialog.css
@@ -14,7 +14,7 @@
dialog {
box-sizing: border-box;
position: absolute;
- top: 50%;
+ top: calc(50% + 40px);
left: 50%;
width: 400px;
max-width: calc(100% - 24px);
diff --git a/design/Header.css b/design/Header.css
index 6ca27ff..a4a2b49 100644
--- a/design/Header.css
+++ b/design/Header.css
@@ -92,6 +92,9 @@ header .card {
grid-area: search;
z-index: 1;
}
+ .search.hidden {
+ display: none;
+ }
.actions {
grid-area: actions;
}
diff --git a/index.html b/index.html
index 25c6a47..a2559b5 100644
--- a/index.html
+++ b/index.html
@@ -2,7 +2,7 @@
-
+
Icons
diff --git a/source/Canvas.js b/source/Canvas.js
index 9da3777..8146130 100644
--- a/source/Canvas.js
+++ b/source/Canvas.js
@@ -61,17 +61,26 @@ export default class Canvas {
/**
* Shows the Icons
- * @param {Icon[]} icons
+ * @param {Icon[]} icons
+ * @param {String=} text
* @returns {Void}
*/
- showIcons(icons) {
+ showIcons(icons, text = "") {
+ if (this.#icons) {
+ if (text && !icons.length) {
+ this.#icons.style.display = "none";
+ } else {
+ this.#icons.style.display = "flex";
+ }
+ }
+
if (this.#empty) {
this.#empty.style.display = icons.length ? "none" : "block";
}
if (this.#list) {
this.#list.innerHTML = "";
for (const icon of icons) {
- this.#list?.append(icon.editElement);
+ this.#list.append(icon.editElement);
}
}
}
diff --git a/source/Main.js b/source/Main.js
index 75b0b16..f5cbedf 100644
--- a/source/Main.js
+++ b/source/Main.js
@@ -36,19 +36,31 @@ function main() {
/**
* Selects the given Project
* @param {Number} projectID
- * @returns {Boolean}
+ * @returns {Void}
*/
function selectProject(projectID) {
const newProject = storage.getProject(projectID);
if (!newProject) {
- return false;
+ return;
}
project = newProject;
storage.selectProject(projectID);
- canvas.setProject(newProject);
search.clear();
- return true;
+ canvas.setProject(project);
+}
+
+/**
+ * Shows the Icons
+ * @returns {Void}
+ */
+function showIcons() {
+ if (!project) {
+ return;
+ }
+
+ const icons = project.filterIcons(search.text);
+ canvas.showIcons(icons, search.text);
}
/**
@@ -66,6 +78,7 @@ async function editProject() {
if (project && project.id === newProject.id) {
canvas.setProject(newProject);
}
+ project = newProject;
selection.closeEdit();
}
@@ -101,10 +114,20 @@ function editIcon() {
storage.setIcon(icon);
project.setIcon(icon);
- canvas.showIcons(project.icons);
+ search.removeIcon(icon);
+ showIcons();
icons.closeEdit();
}
+/**
+ * Searches the Icons
+ * @returns {Void}
+ */
+function searchIcons() {
+ search.search(project.iconKeys);
+ showIcons();
+}
+
/**
@@ -165,17 +188,18 @@ document.addEventListener("click", (e) => {
// Search
case "search-icon":
- search.search();
+ searchIcons();
break;
case "clear-search":
search.clear();
+ showIcons();
break;
// Icons
case "open-add-icon":
- const iconData = search.getIcon(icon);
- if (iconData) {
- icons.openAdd(iconData);
+ const newIcon = search.getIcon(icon);
+ if (newIcon) {
+ icons.openAdd(newIcon);
}
break;
case "edit-icon":
@@ -206,7 +230,7 @@ document.addEventListener("click", (e) => {
*/
document.querySelector(".search input")?.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
- search.search();
+ searchIcons();
}
});
diff --git a/source/Project.js b/source/Project.js
index 603fd09..d1b7c4e 100644
--- a/source/Project.js
+++ b/source/Project.js
@@ -41,6 +41,14 @@ export default class Project {
return Object.values(this.#icons);
}
+ /**
+ * Returns the Icon keys
+ * @returns {String[]}
+ */
+ get iconKeys() {
+ return Object.values(this.#icons).map((icon) => icon.icon);
+ }
+
/**
* Returns true if there is an Icon with the given name
* @param {String} name
@@ -64,4 +72,18 @@ export default class Project {
setIcon(icon) {
this.#icons[icon.id] = icon;
}
+
+ /**
+ * Returns an array with the filtered Icons
+ * @returns {Icon[]}
+ */
+ filterIcons(text) {
+ const result = [];
+ for (const icon of this.icons) {
+ if (!text || icon.includes(text)) {
+ result.push(icon);
+ }
+ }
+ return result;
+ }
}
diff --git a/source/Search.js b/source/Search.js
index 1d8e2f2..dbd8222 100644
--- a/source/Search.js
+++ b/source/Search.js
@@ -1,4 +1,5 @@
-import Icon from "./Icon.js";
+import Icon from "./Icon.js";
+import Utils from "./Utils.js";
@@ -8,7 +9,8 @@ import Icon from "./Icon.js";
export default class Search {
#withTags = true;
-
+ #text = "";
+
/** @type {Object.} */
#data = {};
@@ -36,11 +38,11 @@ export default class Search {
}
/**
- * Returns the Input value
+ * Returns the Text
* @returns {String}
*/
get text() {
- return this.#input?.value || "";
+ return this.#text;
}
/**
@@ -53,17 +55,18 @@ export default class Search {
/**
* Searches new Icons
+ * @param {String[]} iconKeys
* @returns {Promise}
*/
- async search() {
- const text = this.text;
- if (!text) {
+ async search(iconKeys) {
+ this.#text = (this.#input?.value || "").toLowerCase();
+ if (!this.#text) {
return;
}
if (!this.#data.length) {
await this.fetchData();
}
- const icons = this.findIcons(text);
+ const icons = this.findIcons(iconKeys);
this.showIcons(icons);
}
@@ -95,15 +98,13 @@ export default class Search {
/**
* Finds the icons
- * @param {String} text
+ * @param {String[]} iconKeys
* @returns {Icon[]}
*/
- findIcons(text) {
- const search = text.toLowerCase();
+ findIcons(iconKeys) {
const result = [];
-
for (const icon of Object.values(this.#data)) {
- if (icon.includes(search)) {
+ if (!iconKeys.includes(icon.icon) && icon.includes(this.#text)) {
result.push(icon);
}
}
@@ -139,11 +140,27 @@ export default class Search {
return true;
}
+ /**
+ * Removes the given Icon
+ * @param {Icon} icon
+ * @returns {Void}
+ */
+ removeIcon(icon) {
+ if (!this.#text || !this.#list) {
+ return;
+ }
+ const element = this.#list.querySelector(`[data-icon=${icon.icon}]`);
+ if (element) {
+ Utils.removeElement(element);
+ }
+ }
+
/**
* Clears the Search
* @returns {Void}
*/
clear() {
+ this.#text = "";
if (this.#input) {
this.#input.value = "";
}
diff --git a/source/Selection.js b/source/Selection.js
index 06e882e..b2d199f 100644
--- a/source/Selection.js
+++ b/source/Selection.js
@@ -70,7 +70,7 @@ export default class Selection {
for (const project of projects) {
const li = document.createElement("li");
li.dataset.action = "select-project";
- li.dataset.project = project.id;
+ li.dataset.project = String(project.id);
if (project.isSelected) {
li.className = "selected";
}
@@ -87,14 +87,14 @@ export default class Selection {
editBtn.innerHTML = "Edit";
editBtn.className = "btn btn-small";
editBtn.dataset.action = "open-edit-project";
- editBtn.dataset.project = project.id;
+ editBtn.dataset.project = String(project.id);
buttons.appendChild(editBtn);
const deleteBtn = document.createElement("button");
deleteBtn.innerHTML = "Delete";
deleteBtn.className = "btn btn-small";
deleteBtn.dataset.action = "open-delete-project";
- deleteBtn.dataset.project = project.id;
+ deleteBtn.dataset.project = String(project.id);
buttons.appendChild(deleteBtn);
this.#selectList?.appendChild(li);