Press Archive - Percona
` : ''; return ` ${img}
${hit.title}
${hit.description || ''}
`; } function sourceIndex(indexName, panelId) { return instantsearch.widgets.index({ indexName }).addWidgets([ instantsearch.widgets.configure({ hitsPerPage: resultsPerTab }), instantsearch.widgets.hits({ container: '#' + panelId + ' .hits', templates: { item: hitTemplate } }), makeStatsWidget(panelId), ]); } search.addWidgets([ sourceIndex('percona_main_site', 'results1'), sourceIndex('percona_docs_pages', 'results2'), sourceIndex('percona_blog_articles', 'results3'), sourceIndex('percona_community_blog_pages', 'results4'), ]); search.on('render', () => { clearActive(); scheduleReposition(); // new query: reset the "user picked a tab" pin and scroll lists to the top const q = (search.helper ? search.helper.state.query : '').trim(); if (q !== lastQuery) { lastQuery = q; userChoseTab = false; popupEl.querySelectorAll('.results').forEach(r => { r.scrollTop = 0; }); } if (q !== '') maybeAutoSwitch(); }); search.start(); function getInput() { return container.querySelector('.ais-SearchBox-input'); } function openPopup() { updateDropPositions(); popupEl.classList.add('open'); const input = getInput(); if (input) input.setAttribute('aria-expanded', 'true'); } function closePopup() { popupEl.classList.remove('open'); clearActive(); const input = getInput(); if (input) input.setAttribute('aria-expanded', 'false'); } function setupCombobox() { const input = getInput(); if (!input) return; input.setAttribute('role', 'combobox'); input.setAttribute('aria-expanded', 'false'); input.setAttribute('aria-controls', 'search-popup'); input.setAttribute('aria-haspopup', 'listbox'); input.setAttribute('aria-autocomplete', 'list'); input.setAttribute('aria-label', 'Search percona.com'); } setupCombobox(); function visibleHitLinks() { const activePanel = popupEl.querySelector('.results.active'); return activePanel ? Array.from(activePanel.querySelectorAll('.hit-link')) : []; } function clearActive() { activeIndex = -1; popupEl.querySelectorAll('.hit-link.is-active').forEach(el => { el.classList.remove('is-active'); el.removeAttribute('aria-selected'); }); const input = getInput(); if (input) input.removeAttribute('aria-activedescendant'); } function setActive(index, opts = {}) { const { scroll = true } = opts; const links = visibleHitLinks(); if (!links.length) return; activeIndex = (index + links.length) % links.length; links.forEach((el, i) => { const on = i === activeIndex; el.classList.toggle('is-active', on); if (on) { if (!el.id) el.id = 'hit-option-' + i; el.setAttribute('aria-selected', 'true'); // keyboard nav keeps the highlighted row inside the scroll area; // hovering must not scroll, or the list jumps under the pointer if (scroll) el.scrollIntoView({ block: 'nearest' }); const input = getInput(); if (input) input.setAttribute('aria-activedescendant', el.id); } else { el.removeAttribute('aria-selected'); } }); } document.querySelectorAll('.search-popup .tab').forEach(tab => { tab.addEventListener('click', () => activateTab(tab, { byUser: true })); tab.addEventListener('keydown', (e) => { const tabsArr = Array.from(document.querySelectorAll('.search-popup .tab')); const i = tabsArr.indexOf(tab); let next = null; if (e.key === 'ArrowRight') next = tabsArr[(i + 1) % tabsArr.length]; if (e.key === 'ArrowLeft') next = tabsArr[(i - 1 + tabsArr.length) % tabsArr.length]; if (next) { e.preventDefault(); next.focus(); activateTab(next, { byUser: true }); } }); }); function activateTab(tab, opts = {}) { if (opts.byUser) userChoseTab = true; document.querySelectorAll('.search-popup .tab').forEach(t => { t.classList.remove('active'); t.setAttribute('aria-selected', 'false'); t.setAttribute('tabindex', '-1'); }); document.querySelectorAll('.search-popup .results').forEach(r => r.classList.remove('active')); tab.classList.add('active'); tab.setAttribute('aria-selected', 'true'); tab.setAttribute('tabindex', '0'); const panel = document.getElementById(tab.dataset.target); panel.classList.add('active'); panel.scrollTop = 0; clearActive(); updateFooter(); } function expandSearch() { updateDropPositions(); container.classList.add('expanded'); const delay = isDropdownMode() ? 0 : 260; setTimeout(() => { // the wrap is laid out by now, so measure it for real — measuring too // early estimated 56px and let the popup slide under the input bar, // hiding the tab row and the first hit updateDropPositions(); const input = getInput(); if (input) { input.focus(); if (input.value.trim() !== '') openPopup(); } }, delay); } // focusIcon: only when the user deliberately dismissed the search (close // button, Escape, icon toggle). On an outside click focus belongs wherever // they clicked, so don't yank it back to the header. function collapseSearch(opts = {}) { const { focusIcon = true } = opts; const input = getInput(); if (input) { input.value = ''; search.helper.setQuery('').search(); } closePopup(); container.classList.remove('expanded'); if (focusIcon) iconBtn.focus(); } iconBtn.addEventListener('click', () => { if (isDropdownMode() && container.classList.contains('expanded')) { collapseSearch(); } else { expandSearch(); } }); collapseBtn.addEventListener('click', () => collapseSearch()); container.addEventListener('keydown', (e) => { const input = getInput(); if (!input || e.target !== input) return; if (e.key === 'Enter') { e.preventDefault(); const links = visibleHitLinks(); if (popupEl.classList.contains('open') && activeIndex >= 0 && links[activeIndex]) { links[activeIndex].click(); } else { const q = input.value.trim(); if (q !== '') goToSearchPage(q); } return; } if (!popupEl.classList.contains('open')) return; if (e.key === 'ArrowDown') { e.preventDefault(); setActive(activeIndex + 1); } else if (e.key === 'ArrowUp') { e.preventDefault(); setActive(activeIndex - 1); } else if (e.key === 'Home' && activeIndex >= 0) { e.preventDefault(); setActive(0); } else if (e.key === 'End' && activeIndex >= 0) { e.preventDefault(); setActive(visibleHitLinks().length - 1); } }); popupEl.addEventListener('mousemove', (e) => { const link = e.target.closest('.hit-link'); if (!link) { if (activeIndex !== -1) clearActive(); return; } const links = visibleHitLinks(); const i = links.indexOf(link); if (i !== -1 && i !== activeIndex) setActive(i, { scroll: false }); }); popupEl.addEventListener('mouseleave', () => { clearActive(); }); document.addEventListener('focusin', (e) => { if (container.contains(e.target) && e.target.matches('.ais-SearchBox-input')) { if (e.target.value.trim() !== '') openPopup(); } }); /* Outside-click close. composedPath() is captured at dispatch time, so it still works if a re-render detaches the clicked node before the event bubbles here; the pointerdown flag is a fallback for older browsers. */ let pressedInside = false; document.addEventListener('pointerdown', (e) => { pressedInside = container.contains(e.target); }, true); document.addEventListener('click', (e) => { const path = typeof e.composedPath === 'function' ? e.composedPath() : null; const inside = path ? path.includes(container) : container.contains(e.target); if (inside || pressedInside) return; // full collapse, not just closePopup() — leaving the expanded input bar // behind puts it on top of whatever nav menu the user just opened if (container.classList.contains('expanded')) collapseSearch({ focusIcon: false }); else closePopup(); }); // keyboard equivalent: tabbing or focusing into a nav menu also dismisses it document.addEventListener('focusin', (e) => { if (!container.classList.contains('expanded')) return; if (container.contains(e.target)) return; collapseSearch({ focusIcon: false }); }); document.addEventListener('keydown', (e) => { if (e.key !== 'Escape') return; if (popupEl.classList.contains('open')) { closePopup(); const input = getInput(); if (input) input.focus(); } else if (container.classList.contains('expanded')) { collapseSearch(); } }); })();
percona goat

PrEss RELEasEs

The latest from Percona — product releases, company news, community updates, and everything in between.

Press
|
June 30, 2026
Percona and HexaCluster Collaborate to Help Enterprises Migrate off Proprietary Databases
New partnership pairs Percona migration expertise with HexaCluster tooling to move legacy and proprietary databases to open source more efficiently an...
Press
|
April 16, 2026
Percona Declares ‘The Way is Open’ in Bold Rebrand as the Industry’s Loudest Challenger
Press
|
April 16, 2026
Percona Announces OpenEverest, an Independent Open Source Project for Modern Data Management

Far
Enough.

Said no pioneer ever.
MySQL, PostgreSQL, InnoDB, MariaDB, MongoDB and Kubernetes are trademarks for their respective owners.
© 2026 Percona All Rights Reserved