* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.search-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 2rem;
color: white;
}
.search-header {
text-align: center;
margin-bottom: 3rem;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.search-title {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 1rem;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.search-subtitle {
font-size: 1.1rem;
color: rgba(255, 255, 255, 0.8);
font-weight: 400;
}
.search-demos {
max-width: 1000px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.search-demo {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 2rem;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.demo-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 1.5rem;
text-align: center;
color: rgba(255, 255, 255, 0.9);
}
.search-wrapper {
position: relative;
}
.search-box {
position: relative;
display: flex;
align-items: center;
}
.search-input {
width: 100%;
padding: 1rem 1.5rem;
border: none;
border-radius: 50px;
font-size: 1rem;
background: rgba(255, 255, 255, 0.9);
color: #333;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
outline: none;
}
.search-input::placeholder {
color: rgba(51, 51, 51, 0.6);
}
.search-input:focus {
background: white;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
.search-btn {
position: absolute;
right: 8px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
color: white;
}
.search-btn:hover {
transform: scale(1.1);
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.search-icon {
transition: transform 0.3s ease;
}
.search-btn:hover .search-icon {
transform: scale(1.1);
}
/* Classic Animated Search */
.classic .search-box {
position: relative;
overflow: hidden;
}
.search-border {
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 3px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
transform: translateX(-50%);
border-radius: 2px;
}
.classic .search-input {
border-radius: 12px;
padding-right: 60px;
}
.classic .search-input:focus + .search-btn + .search-border {
width: 100%;
}
/* Expanding Search */
.expanding .search-box {
width: 50px;
height: 50px;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
border-radius: 25px;
background: rgba(255, 255, 255, 0.9);
overflow: hidden;
}
.expanding .search-trigger {
position: absolute;
left: 15px;
top: 15px;
background: none;
border: none;
color: #667eea;
cursor: pointer;
z-index: 3;
transition: opacity 0.3s ease;
}
.expanding .search-input {
position: absolute;
left: 50px;
top: 0;
width: calc(100% - 100px);
height: 50px;
background: transparent;
border-radius: 0;
padding: 0 1rem;
opacity: 0;
transition: opacity 0.3s ease;
}
.expanding .search-close {
position: absolute;
right: 15px;
top: 17px;
background: none;
border: none;
color: #667eea;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 3;
}
.expanding.expanded .search-box {
width: 100%;
}
.expanding.expanded .search-trigger {
opacity: 0;
pointer-events: none;
}
.expanding.expanded .search-input {
opacity: 1;
}
.expanding.expanded .search-close {
opacity: 1;
}
/* Glassmorphism Search */
.glassmorphism .search-box {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 0.5rem;
}
.glassmorphism .search-input {
background: transparent;
color: white;
border-radius: 15px;
padding-left: 50px;
padding-right: 50px;
}
.glassmorphism .search-input::placeholder {
color: rgba(255, 255, 255, 0.7);
}
.glassmorphism .search-icon {
position: absolute;
left: 20px;
color: rgba(255, 255, 255, 0.8);
z-index: 2;
}
.glassmorphism .voice-btn {
position: absolute;
right: 15px;
background: rgba(255, 255, 255, 0.2);
border: none;
border-radius: 10px;
width: 35px;
height: 35px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
color: white;
}
.glassmorphism .voice-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
/* Advanced Search */
.advanced .search-box {
position: relative;
}
.search-input-wrapper {
position: relative;
background: white;
border-radius: 15px;
display: flex;
align-items: center;
padding: 0.75rem 1rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.search-input-wrapper:focus-within {
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
.advanced .search-icon {
color: #667eea;
margin-right: 1rem;
}
.advanced .search-input {
flex: 1;
background: transparent;
border: none;
padding: 0;
font-size: 1rem;
color: #333;
}
.search-actions {
display: flex;
gap: 0.5rem;
margin-left: 1rem;
}
.search-actions button {
background: rgba(102, 126, 234, 0.1);
border: none;
border-radius: 8px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
color: #667eea;
}
.search-actions button:hover {
background: rgba(102, 126, 234, 0.2);
transform: scale(1.05);
}
/* Suggestions Dropdown */
.suggestions-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
margin-top: 0.5rem;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10;
max-height: 300px;
overflow-y: auto;
}
.suggestions-dropdown.show {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.suggestions-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem 0.5rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.suggestions-title {
font-weight: 600;
color: #333;
font-size: 0.875rem;
}
.clear-history {
background: none;
border: none;
color: #667eea;
font-size: 0.875rem;
cursor: pointer;
padding: 0.25rem 0.5rem;
border-radius: 4px;
transition: background 0.3s ease;
}
.clear-history:hover {
background: rgba(102, 126, 234, 0.1);
}
.suggestions-list {
list-style: none;
padding: 0.5rem 0;
}
.suggestion-item {
display: flex;
align-items: center;
padding: 0.75rem 1.5rem;
cursor: pointer;
transition: background 0.3s ease;
gap: 1rem;
}
.suggestion-item:hover {
background: rgba(102, 126, 234, 0.05);
}
.suggestion-item.active {
background: rgba(102, 126, 234, 0.1);
}
.suggestion-icon {
color: #667eea;
flex-shrink: 0;
}
.suggestion-text {
flex: 1;
color: #333;
font-size: 0.95rem;
}
.suggestion-type {
font-size: 0.75rem;
color: #999;
background: rgba(0, 0, 0, 0.05);
padding: 0.25rem 0.5rem;
border-radius: 12px;
}
/* Search Results */
.search-results {
max-width: 1000px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 2rem;
border: 1px solid rgba(255, 255, 255, 0.2);
opacity: 0;
visibility: hidden;
transform: translateY(20px);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.search-results.show {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.results-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.results-header h3 {
color: rgba(255, 255, 255, 0.9);
font-size: 1.25rem;
}
.results-count {
color: rgba(255, 255, 255, 0.7);
font-size: 0.875rem;
}
.results-list {
display: grid;
gap: 1rem;
}
.result-item {
background: rgba(255, 255, 255, 0.1);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
cursor: pointer;
}
.result-item:hover {
background: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
}
.result-title {
color: white;
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.result-description {
color: rgba(255, 255, 255, 0.8);
font-size: 0.9rem;
line-height: 1.5;
}
.result-url {
color: rgba(255, 255, 255, 0.6);
font-size: 0.8rem;
margin-top: 0.5rem;
}
/* Voice Recording Animation */
.voice-recording {
animation: voice-pulse 1.5s ease-in-out infinite;
}
@keyframes voice-pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
/* Loading Animation */
.search-loading {
position: relative;
}
.search-loading::after {
content: '';
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
border: 2px solid rgba(102, 126, 234, 0.3);
border-top: 2px solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: translateY(-50%) rotate(0deg); }
100% { transform: translateY(-50%) rotate(360deg); }
}
/* Responsive Design */
@media (max-width: 768px) {
.search-container {
padding: 1rem;
}
.search-title {
font-size: 2rem;
}
.search-demos {
grid-template-columns: 1fr;
gap: 1.5rem;
}
.search-demo {
padding: 1.5rem;
}
.search-input {
font-size: 0.9rem;
}
}
@media (max-width: 480px) {
.search-title {
font-size: 1.75rem;
}
.search-demo {
padding: 1rem;
}
.suggestions-dropdown {
margin-left: -1rem;
margin-right: -1rem;
}
}
class AnimatedSearchBar {
constructor() {
this.searchInputs = document.querySelectorAll('.search-input');
this.expandingSearch = document.querySelector('.expanding');
this.advancedSearch = document.getElementById('advancedSearch');
this.suggestionsDropdown = document.getElementById('suggestionsDropdown');
this.suggestionsList = document.getElementById('suggestionsList');
this.searchResults = document.getElementById('searchResults');
this.resultsList = document.getElementById('resultsList');
this.resultsCount = document.getElementById('resultsCount');
this.isVoiceRecording = false;
this.searchHistory = JSON.parse(localStorage.getItem('searchHistory') || '[]');
this.currentSuggestionIndex = -1;
this.mockResults = [
{
title: "JavaScript ES6 Features Guide",
description: "Comprehensive guide to modern JavaScript features including arrow functions, destructuring, and async/await.",
url: "https://example.com/js-es6-guide"
},
{
title: "React Component Best Practices",
description: "Learn the best practices for building reusable and maintainable React components.",
url: "https://example.com/react-best-practices"
},
{
title: "CSS Animation Techniques",
description: "Master CSS animations with keyframes, transitions, and transform properties.",
url: "https://example.com/css-animations"
},
{
title: "Web Development Roadmap 2024",
description: "Complete roadmap for becoming a full-stack web developer in 2024.",
url: "https://example.com/web-dev-roadmap"
}
];
this.suggestions = [
{ text: 'javascript tutorials', type: 'Popular', icon: 'settings' },
{ text: 'react components', type: 'Recent', icon: 'smile' },
{ text: 'css animations', type: 'Trending', icon: 'zap' },
{ text: 'web development', type: 'Popular', icon: 'monitor' }
];
this.init();
}
init() {
this.setupSearchInputs();
this.setupExpandingSearch();
this.setupAdvancedSearch();
this.setupVoiceSearch();
this.setupKeyboardNavigation();
this.setupClickOutside();
this.loadSearchHistory();
}
setupSearchInputs() {
this.searchInputs.forEach(input => {
input.addEventListener('input', (e) => {
this.handleSearchInput(e);
});
input.addEventListener('focus', (e) => {
this.handleSearchFocus(e);
});
input.addEventListener('blur', (e) => {
setTimeout(() => this.handleSearchBlur(e), 150);
});
input.addEventListener('keydown', (e) => {
this.handleSearchKeydown(e);
});
});
}
setupExpandingSearch() {
const trigger = this.expandingSearch?.querySelector('.search-trigger');
const closeBtn = this.expandingSearch?.querySelector('.search-close');
const input = this.expandingSearch?.querySelector('.search-input');
if (trigger) {
trigger.addEventListener('click', () => {
this.expandingSearch.classList.add('expanded');
setTimeout(() => input?.focus(), 300);
});
}
if (closeBtn) {
closeBtn.addEventListener('click', () => {
this.expandingSearch.classList.remove('expanded');
input.value = '';
});
}
}
setupAdvancedSearch() {
if (!this.advancedSearch) return;
this.advancedSearch.addEventListener('input', (e) => {
this.updateSuggestions(e.target.value);
});
this.advancedSearch.addEventListener('focus', () => {
this.showSuggestions();
});
this.suggestionsList?.addEventListener('click', (e) => {
const suggestionItem = e.target.closest('.suggestion-item');
if (suggestionItem) {
const value = suggestionItem.dataset.value;
this.selectSuggestion(value);
}
});
const clearBtn = document.querySelector('.clear-history');
clearBtn?.addEventListener('click', () => {
this.clearSearchHistory();
});
}
setupVoiceSearch() {
const voiceBtns = document.querySelectorAll('.voice-btn');
voiceBtns.forEach(btn => {
btn.addEventListener('click', () => {
this.toggleVoiceSearch(btn);
});
});
}
setupKeyboardNavigation() {
document.addEventListener('keydown', (e) => {
if (!this.suggestionsDropdown?.classList.contains('show')) return;
const suggestions = this.suggestionsList?.querySelectorAll('.suggestion-item');
if (!suggestions?.length) return;
switch (e.key) {
case 'ArrowDown':
e.preventDefault();
this.currentSuggestionIndex = Math.min(
this.currentSuggestionIndex + 1,
suggestions.length - 1
);
this.highlightSuggestion(suggestions);
break;
case 'ArrowUp':
e.preventDefault();
this.currentSuggestionIndex = Math.max(
this.currentSuggestionIndex - 1,
-1
);
this.highlightSuggestion(suggestions);
break;
case 'Enter':
e.preventDefault();
if (this.currentSuggestionIndex >= 0) {
const selectedSuggestion = suggestions[this.currentSuggestionIndex];
const value = selectedSuggestion.dataset.value;
this.selectSuggestion(value);
}
break;
case 'Escape':
this.hideSuggestions();
this.advancedSearch?.blur();
break;
}
});
}
setupClickOutside() {
document.addEventListener('click', (e) => {
if (!e.target.closest('.advanced')) {
this.hideSuggestions();
}
});
}
handleSearchInput(e) {
const query = e.target.value.trim();
if (query.length > 0) {
this.showSearchLoading(e.target);
setTimeout(() => {
this.hideSearchLoading(e.target);
this.performSearch(query);
}, 800);
} else {
this.hideSearchResults();
}
}
handleSearchFocus(e) {
if (e.target === this.advancedSearch) {
this.showSuggestions();
}
}
handleSearchBlur(e) {
if (e.target === this.advancedSearch) {
this.hideSuggestions();
}
}
handleSearchKeydown(e) {
if (e.key === 'Enter') {
e.preventDefault();
const query = e.target.value.trim();
if (query) {
this.performSearch(query);
this.addToSearchHistory(query);
}
}
}
updateSuggestions(query) {
if (!query.trim()) {
this.loadSearchHistory();
return;
}
const filteredSuggestions = this.suggestions.filter(suggestion =>
suggestion.text.toLowerCase().includes(query.toLowerCase())
);
this.renderSuggestions(filteredSuggestions);
}
renderSuggestions(suggestions) {
if (!this.suggestionsList) return;
this.suggestionsList.innerHTML = suggestions.map(suggestion => `
<li class="suggestion-item" data-value="${suggestion.text}">
<svg class="suggestion-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
${this.getSuggestionIcon(suggestion.icon)}
</svg>
<span class="suggestion-text">${suggestion.text}</span>
<span class="suggestion-type">${suggestion.type}</span>
</li>
`).join('');
this.currentSuggestionIndex = -1;
}
getSuggestionIcon(iconType) {
const icons = {
settings: '<circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2"/><path d="M19.4 15C19.2 15.3 19.1 15.6 19.1 16S19.2 16.7 19.4 17L20.7 18.3C20.9 18.5 20.9 18.9 20.7 19.1L19.1 20.7C18.9 20.9 18.5 20.9 18.3 20.7L17 19.4C16.7 19.6 16.4 19.7 16 19.7S15.3 19.6 15 19.4L13.7 20.7C13.5 20.9 13.1 20.9 12.9 20.7L11.3 19.1C11.1 18.9 11.1 18.5 11.3 18.3L12.6 17C12.4 16.7 12.3 16.4 12.3 16S12.4 15.3 12.6 15L11.3 13.7C11.1 13.5 11.1 13.1 11.3 12.9L12.9 11.3C13.1 11.1 13.5 11.1 13.7 11.3L15 12.6C15.3 12.4 15.6 12.3 16 12.3S16.7 12.4 17 12.6L18.3 11.3C18.5 11.1 18.9 11.1 19.1 11.3L20.7 12.9C20.9 13.1 20.9 13.5 20.7 13.7L19.4 15Z" stroke="currentColor" stroke-width="2"/>',
smile: '<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><path d="M8 14S9.5 16 12 16S16 14 16 14" stroke="currentColor" stroke-width="2"/><line x1="9" y1="9" x2="9.01" y2="9" stroke="currentColor" stroke-width="2"/><line x1="15" y1="9" x2="15.01" y2="9" stroke="currentColor" stroke-width="2"/>',
zap: '<path d="M13 2L3 14H12L11 22L21 10H12L13 2Z" stroke="currentColor" stroke-width="2"/>',
monitor: '<rect x="2" y="3" width="20" height="14" rx="2" ry="2" stroke="currentColor" stroke-width="2"/><line x1="8" y1="21" x2="16" y2="21" stroke="currentColor" stroke-width="2"/><line x1="12" y1="17" x2="12" y2="21" stroke="currentColor" stroke-width="2"/>'
};
return icons[iconType] || icons.settings;
}
highlightSuggestion(suggestions) {
suggestions.forEach((item, index) => {
item.classList.toggle('active', index === this.currentSuggestionIndex);
});
}
selectSuggestion(value) {
if (this.advancedSearch) {
this.advancedSearch.value = value;
this.performSearch(value);
this.addToSearchHistory(value);
this.hideSuggestions();
}
}
showSuggestions() {
if (this.suggestionsDropdown) {
this.suggestionsDropdown.classList.add('show');
}
}
hideSuggestions() {
if (this.suggestionsDropdown) {
this.suggestionsDropdown.classList.remove('show');
this.currentSuggestionIndex = -1;
}
}
showSearchLoading(input) {
input.parentElement.classList.add('search-loading');
}
hideSearchLoading(input) {
input.parentElement.classList.remove('search-loading');
}
performSearch(query) {
const filteredResults = this.mockResults.filter(result =>
result.title.toLowerCase().includes(query.toLowerCase()) ||
result.description.toLowerCase().includes(query.toLowerCase())
);
this.displaySearchResults(filteredResults, query);
}
displaySearchResults(results, query) {
if (!this.searchResults || !this.resultsList || !this.resultsCount) return;
this.resultsCount.textContent = `${results.length} result${results.length !== 1 ? 's' : ''} for "${query}"`;
this.resultsList.innerHTML = results.map(result => `
<div class="result-item">
<div class="result-title">${this.highlightSearchTerm(result.title, query)}</div>
<div class="result-description">${this.highlightSearchTerm(result.description, query)}</div>
<div class="result-url">${result.url}</div>
</div>
`).join('');
this.searchResults.classList.add('show');
}
highlightSearchTerm(text, term) {
if (!term.trim()) return text;
const regex = new RegExp(`(${term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
return text.replace(regex, '<mark style="background: rgba(255, 255, 0, 0.3); padding: 0 2px; border-radius: 2px;">$1</mark>');
}
hideSearchResults() {
if (this.searchResults) {
this.searchResults.classList.remove('show');
}
}
toggleVoiceSearch(button) {
if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
alert('Voice search is not supported in your browser.');
return;
}
if (this.isVoiceRecording) {
this.stopVoiceRecording(button);
} else {
this.startVoiceRecording(button);
}
}
startVoiceRecording(button) {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = 'en-US';
recognition.onstart = () => {
this.isVoiceRecording = true;
button.classList.add('voice-recording');
button.style.background = 'rgba(239, 68, 68, 0.2)';
};
recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript;
const searchInput = button.closest('.search-box').querySelector('.search-input');
if (searchInput) {
searchInput.value = transcript;
this.performSearch(transcript);
this.addToSearchHistory(transcript);
}
};
recognition.onerror = (event) => {
console.error('Speech recognition error:', event.error);
this.stopVoiceRecording(button);
};
recognition.onend = () => {
this.stopVoiceRecording(button);
};
recognition.start();
this.currentRecognition = recognition;
}
stopVoiceRecording(button) {
this.isVoiceRecording = false;
button.classList.remove('voice-recording');
button.style.background = '';
if (this.currentRecognition) {
this.currentRecognition.stop();
this.currentRecognition = null;
}
}
addToSearchHistory(query) {
if (!query.trim()) return;
this.searchHistory = this.searchHistory.filter(item => item !== query);
this.searchHistory.unshift(query);
this.searchHistory = this.searchHistory.slice(0, 10);
localStorage.setItem('searchHistory', JSON.stringify(this.searchHistory));
}
loadSearchHistory() {
if (!this.suggestionsList) return;
const historyItems = this.searchHistory.map(item => ({
text: item,
type: 'Recent',
icon: 'monitor'
}));
this.renderSuggestions([...historyItems, ...this.suggestions].slice(0, 6));
}
clearSearchHistory() {
this.searchHistory = [];
localStorage.removeItem('searchHistory');
this.loadSearchHistory();
}
search(query) {
this.performSearch(query);
this.addToSearchHistory(query);
}
clearResults() {
this.hideSearchResults();
}
setSearchData(data) {
this.mockResults = data;
}
getSearchHistory() {
return [...this.searchHistory];
}
addSuggestion(suggestion) {
this.suggestions.push(suggestion);
}
removeSuggestion(text) {
this.suggestions = this.suggestions.filter(s => s.text !== text);
}
getPerformanceMetrics() {
return {
searchHistory: this.searchHistory.length,
suggestions: this.suggestions.length,
isVoiceSupported: 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window,
memoryUsage: performance.memory ? {
used: Math.round(performance.memory.usedJSHeapSize / 1024 / 1024),
total: Math.round(performance.memory.totalJSHeapSize / 1024 / 1024)
} : 'Not available'
};
}
destroy() {
this.searchInputs.forEach(input => {
input.replaceWith(input.cloneNode(true));
});
if (this.currentRecognition) {
this.currentRecognition.stop();
}
this.searchInputs = null;
this.expandingSearch = null;
this.advancedSearch = null;
this.suggestionsDropdown = null;
}
}
document.addEventListener('DOMContentLoaded', () => {
window.animatedSearchBar = new AnimatedSearchBar();
});
if (typeof module !== 'undefined' && module.exports) {
module.exports = AnimatedSearchBar;
}