feat: Add basic search component, b=no-bug, c=common

This commit is contained in:
mr. m
2026-03-08 12:09:31 +01:00
parent 48d5b32a5a
commit 556beb01b0
4 changed files with 92 additions and 16 deletions

View File

@@ -14,9 +14,7 @@
--inactive-titlebar-opacity: 0.8;
&[zen-library-open="true"] {
visibility: hidden;
opacity: 0;
pointer-events: none;
display: none;
}
}

View File

@@ -31,6 +31,7 @@ ChromeUtils.defineLazyGetter(lazy, "appContentWrapper", function () {
export class ZenLibrary extends MozLitElement {
#initialized = false;
#resizeObserver = null;
#sections = [];
_deletionIdleCallbackId = null;
static properties = {
@@ -72,12 +73,20 @@ export class ZenLibrary extends MozLitElement {
});
});
this.#resizeObserver.observe(this);
for (const Section of Object.values(lazy.ZenLibrarySections)) {
let section = new Section();
this.#sections.push(section);
}
this.#initialized = true;
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener("keydown", this);
for (const section of this.#sections) {
section.remove();
}
this.#sections = [];
if (this.#resizeObserver) {
this.#resizeObserver.disconnect();
this.#resizeObserver = null;
@@ -106,7 +115,7 @@ export class ZenLibrary extends MozLitElement {
<vbox id="zen-library-sidebar-footer"></vbox>
</vbox>
<vbox id="zen-library-content" flex="1" ?large-content=${lazy.ZenLibrarySections[this.activeTab].largeContent}>
${this.#sections.find(section => section.constructor.id === this.activeTab)}
</vbox>
`;
}

View File

@@ -5,7 +5,16 @@
import { html } from "chrome://global/content/vendor/lit.all.mjs";
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
class ZenLibrarySection extends MozLitElement {
let lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", function () {
return new Localization(
["browser/zen-library.ftl"],
true
);
});
class LibrarySection extends MozLitElement {
static largeContent = false;
static get id() {
@@ -17,18 +26,62 @@ class ZenLibrarySection extends MozLitElement {
}
}
class SearchSection extends LibrarySection {
static properties = {
searchTerm: { type: String },
};
connectedCallback() {
this.searchTerm = "";
super.connectedCallback();
}
_onSearchInput(event) {
this.searchTerm = event.target.value;
this.requestUpdate();
}
renderSearchResults() {
return html`${this.searchTerm}`;
}
render() {
return html`
<link rel="stylesheet" href="chrome://browser/content/zen-styles/zen-library.css" />
<hbox class="search-section">
<image src="chrome://browser/skin/zen-icons/search-glass.svg" />
<input
class="search-input"
type="search"
placeholder=${lazy.l10n.formatValueSync("library-search-placeholder")}
@input=${this._onSearchInput}
.value=${this.searchTerm}
/>
</hbox>
<div class="search-results">
${this.renderSearchResults()}
</div>
`;
}
}
export const ZenLibrarySections = {
history: class extends ZenLibrarySection {
history: class extends SearchSection {
static id = "history";
static label = "library-history-section-title";
},
downloads: class extends ZenLibrarySection {
downloads: class extends SearchSection {
static id = "downloads";
static label = "library-downloads-section-title";
},
spaces: class extends ZenLibrarySection {
spaces: class extends LibrarySection {
static largeContent = true;
static id = "spaces";
static label = "library-spaces-section-title";
},
};
for (const section of Object.values(ZenLibrarySections)) {
customElements.define(`zen-library-section-${section.id}`, section)
;
}

View File

@@ -4,16 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
:host {
:host(zen-library) {
transition: transform 0.1s ease-in-out;
transform: translateX(-100%);
z-index: 1;
display: block;
display: flex;
position: absolute;
height: 100%;
}
:host([open]) {
:host(zen-library[open]) {
transform: translateX(0);
}
@@ -26,17 +26,23 @@
height: 100%;
width: 84px;
-moz-window-dragging: drag;
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.025);
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.02);
}
#zen-library-content {
display: flex;
transition: width 0.15s ease-in-out;
width: 45vw;
max-width: 100%;
transition: min-width 0.15s ease-in-out;
min-width: 35rem;
max-width: 80vh;
&[large-content] {
width: 80vw;
min-width: 75rem;
}
& > * {
flex: 1;
display: flex;
flex-direction: column;
}
}
@@ -76,3 +82,13 @@
transform: scale(0.95);
}
}
/* Section: Search Component */
.search-section {
flex: 1;
& .search-input {
width: 100%;
}
}