97 lines
2.5 KiB
TypeScript
97 lines
2.5 KiB
TypeScript
interface SearchBarOptions {
|
|
searchBarSelector?: string;
|
|
buttonSelector?: string;
|
|
}
|
|
|
|
export default class SearchBar {
|
|
private searchBar: HTMLDivElement | null;
|
|
private searchButton: HTMLButtonElement | null;
|
|
private isOpen: boolean = false;
|
|
|
|
constructor(options: SearchBarOptions = {}) {
|
|
this.searchBar = document.querySelector('#search-module') as HTMLDivElement;
|
|
this.searchButton = document.querySelector(
|
|
'.tools-container .search-button'
|
|
) as HTMLButtonElement;
|
|
|
|
this.init();
|
|
}
|
|
|
|
private init(): void {
|
|
if (!this.searchBar || !this.searchButton) return;
|
|
|
|
// Initialiser l'état
|
|
this.isOpen = this.searchBar.hasAttribute('opened');
|
|
this.updateAriaHidden();
|
|
|
|
// Ajouter les event listeners
|
|
this.searchButton.addEventListener('click', this.toggle.bind(this));
|
|
this.searchBar.addEventListener('transitionend', this.handleTransitionEnd.bind(this));
|
|
document.addEventListener('keydown', this.handleKeyDown.bind(this));
|
|
}
|
|
|
|
private toggle(): void {
|
|
if (!this.searchBar) return;
|
|
|
|
this.isOpen = !this.isOpen;
|
|
|
|
if (this.isOpen) {
|
|
this.open();
|
|
} else {
|
|
this.close();
|
|
}
|
|
}
|
|
|
|
public open(): void {
|
|
if (!this.searchBar) return;
|
|
|
|
this.searchBar.removeAttribute('closed');
|
|
this.searchBar.setAttribute('opened', '');
|
|
this.isOpen = true;
|
|
}
|
|
|
|
public close(): void {
|
|
if (!this.searchBar) return;
|
|
|
|
this.searchBar.setAttribute('closed', '');
|
|
this.searchBar.removeAttribute('opened');
|
|
this.isOpen = false;
|
|
}
|
|
|
|
private handleTransitionEnd(): void {
|
|
this.updateAriaHidden();
|
|
}
|
|
|
|
private handleKeyDown(event: KeyboardEvent): void {
|
|
if (event.key === 'Escape' && this.isOpen) {
|
|
this.close();
|
|
}
|
|
}
|
|
|
|
private updateAriaHidden(): void {
|
|
if (!this.searchBar) return;
|
|
|
|
if (this.searchBar.hasAttribute('closed')) {
|
|
this.searchBar.setAttribute('aria-hidden', 'true');
|
|
} else {
|
|
this.searchBar.setAttribute('aria-hidden', 'false');
|
|
}
|
|
}
|
|
|
|
public isSearchBarOpen(): boolean {
|
|
return this.isOpen;
|
|
}
|
|
|
|
public destroy(): void {
|
|
if (!this.searchBar || !this.searchButton) return;
|
|
|
|
this.searchButton.removeEventListener('click', this.toggle.bind(this));
|
|
this.searchBar.removeEventListener('transitionend', this.handleTransitionEnd.bind(this));
|
|
}
|
|
}
|
|
|
|
// Fonction de compatibilité pour l'import existant
|
|
export function searchBarInit(): SearchBar {
|
|
return new SearchBar();
|
|
}
|