Files
milinda-pitch/js/components/search-bar.js

105 lines
2.9 KiB
JavaScript

/**
* Search Bar Component
* Search input with icon
*/
class SearchBar extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
this.render();
this.addEventListeners();
}
addEventListeners() {
const input = this.shadowRoot.querySelector(".search-input");
const form = this.shadowRoot.querySelector(".search-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
this.dispatchEvent(
new CustomEvent("search", {
detail: { query: input.value },
bubbles: true,
composed: true,
})
);
});
input.addEventListener("input", (e) => {
this.dispatchEvent(
new CustomEvent("search-input", {
detail: { query: e.target.value },
bubbles: true,
composed: true,
})
);
});
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.search-form {
display: flex;
align-items: center;
position: relative;
padding: var(--spacing-sm, 0.5rem) var(--spacing-sm, 0.5rem);
background-color: #951D51;
}
.search-icon {
position: absolute;
left: var(--spacing-md, 1rem);
width: 20px;
height: 20px;
color: var(--color-text-light, #64748b);
pointer-events: none;
}
.search-input {
width: 100%;
padding: var(--spacing-sm, 0.5rem) var(--spacing-md, 1rem);
padding-left: calc(var(--spacing-md, 1rem) + 20px + var(--spacing-sm, 0.5rem));
font-size: var(--font-size-sm, 0.875rem);
color: var(--color-text, #1e293b);
background-color: var(--color-background-tertiary, #f1f5f9);
border: 1px solid transparent;
border-radius: var(--radius-lg, 0.75rem);
outline: none;
transition: all var(--transition-fast, 150ms ease);
}
.search-input::placeholder {
color: var(--color-text-light, #64748b);
}
.search-input:focus {
background-color: var(--color-background, #ffffff);
border-color: var(--color-primary, #2563eb);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
</style>
<form class="search-form" role="search">
<svg class="search-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
</svg>
<input
type="search"
class="search-input"
placeholder="Search books, authors..."
aria-label="Search books and authors"
>
</form>
`;
}
}
customElements.define("search-bar", SearchBar);