UNPKG

stylescape

Version:

Stylescape is a visual identity framework developed by Scape Agency.

110 lines 3.81 kB
export class FilterManager { constructor(inputSelectorOrElement, options = {}) { this.debounceTimer = null; this.handleInput = () => { if (this.debounceTimer) { clearTimeout(this.debounceTimer); } this.debounceTimer = window.setTimeout(() => { this.filter(); }, this.options.debounce); }; this.input = typeof inputSelectorOrElement === "string" ? document.querySelector(inputSelectorOrElement) : inputSelectorOrElement; this.options = { itemSelector: options.itemSelector ?? ".filter-item", searchIn: options.searchIn ?? "textContent", debounce: options.debounce ?? 150, caseSensitive: options.caseSensitive ?? false, minChars: options.minChars ?? 0, hiddenClass: options.hiddenClass ?? "filter--hidden", matchClass: options.matchClass ?? "filter--match", onFilter: options.onFilter ?? (() => { }), onEmpty: options.onEmpty ?? (() => { }), }; this.items = []; if (!this.input) { console.warn("[Stylescape] FilterManager input not found"); return; } this.init(); } filter(query) { const searchQuery = query ?? this.input?.value ?? ""; return this.applyFilter(searchQuery); } clear() { if (this.input) { this.input.value = ""; } this.showAll(); } showAll() { this.items.forEach((item) => { item.classList.remove(this.options.hiddenClass); item.classList.remove(this.options.matchClass); }); } refresh() { this.items = Array.from(document.querySelectorAll(this.options.itemSelector)); } getMatches() { return this.items.filter((item) => !item.classList.contains(this.options.hiddenClass)); } destroy() { this.input?.removeEventListener("input", this.handleInput); this.input = null; this.items = []; } init() { this.refresh(); this.input?.addEventListener("input", this.handleInput); if (this.input?.value) { this.filter(); } } applyFilter(query) { if (query.length < this.options.minChars) { this.showAll(); return this.items; } const normalizedQuery = this.options.caseSensitive ? query : query.toLowerCase(); const matches = []; this.items.forEach((item) => { const content = this.getSearchContent(item); const normalizedContent = this.options.caseSensitive ? content : content.toLowerCase(); const isMatch = normalizedContent.includes(normalizedQuery); item.classList.toggle(this.options.hiddenClass, !isMatch); item.classList.toggle(this.options.matchClass, isMatch); if (isMatch) { matches.push(item); } }); this.options.onFilter(matches, query); if (matches.length === 0 && query.length > 0) { this.options.onEmpty(query); } return matches; } getSearchContent(item) { const searchIn = Array.isArray(this.options.searchIn) ? this.options.searchIn : [this.options.searchIn]; return searchIn .map((attr) => { if (attr === "textContent") { return item.textContent || ""; } return item.getAttribute(attr) || item.dataset[attr] || ""; }) .join(" "); } } export default FilterManager; //# sourceMappingURL=FilterManager.js.map