Files
breadcrumb-the-shire/web/js/components/app-nav-history.js

97 lines
2.6 KiB
JavaScript
Raw Normal View History

/**
* Browser history integration handles back/forward navigation state.
*/
import { isEditableTarget } from '../core/app-form-utils.js';
import { resolveHost } from '../core/app-dom.js';
export function initNavHistory(root = document, options = {}) {
const {
backSelector = '#global-back',
forwardSelector = '#global-forward',
} = options;
const host = resolveHost(root);
const back = host.querySelector(backSelector);
const forward = host.querySelector(forwardSelector);
if (!back && !forward) {
return { destroy: () => {} };
}
2026-02-04 23:31:53 +01:00
2026-03-05 12:51:53 +01:00
const setDisabledState = (link, disabled) => {
link.setAttribute('aria-disabled', disabled ? 'true' : 'false');
link.classList.toggle('is-disabled', disabled);
if (disabled) {
link.setAttribute('tabindex', '-1');
} else {
link.removeAttribute('tabindex');
}
};
2026-02-04 23:31:53 +01:00
const updateHistoryButtons = () => {
const hasHistory = window.history.length > 1;
if (back instanceof HTMLElement) {
setDisabledState(back, !hasHistory);
}
if (forward instanceof HTMLElement) {
setDisabledState(forward, !hasHistory);
}
};
2026-02-04 23:31:53 +01:00
const onKeyDown = (event) => {
if (!event.altKey || event.metaKey || event.ctrlKey) {
return;
}
if (isEditableTarget(event.target)) {
return;
}
2026-02-11 19:28:12 +01:00
if (event.key === 'ArrowLeft') {
if (window.history.length > 1) {
event.preventDefault();
window.history.back();
}
} else if (event.key === 'ArrowRight') {
if (window.history.length > 1) {
event.preventDefault();
window.history.forward();
}
}
};
2026-02-11 19:28:12 +01:00
document.addEventListener('keydown', onKeyDown);
const onBackClick = (event) => {
event.preventDefault();
if (window.history.length > 1) {
window.history.back();
}
};
if (back instanceof HTMLElement) {
back.addEventListener('click', onBackClick);
2026-02-04 23:31:53 +01:00
}
const onForwardClick = (event) => {
event.preventDefault();
if (window.history.length > 1) {
window.history.forward();
}
};
if (forward instanceof HTMLElement) {
forward.addEventListener('click', onForwardClick);
2026-02-04 23:31:53 +01:00
}
window.addEventListener('popstate', updateHistoryButtons);
updateHistoryButtons();
const destroy = () => {
document.removeEventListener('keydown', onKeyDown);
if (back instanceof HTMLElement) {
back.removeEventListener('click', onBackClick);
}
if (forward instanceof HTMLElement) {
forward.removeEventListener('click', onForwardClick);
}
window.removeEventListener('popstate', updateHistoryButtons);
};
2026-02-04 23:31:53 +01:00
return { destroy, update: updateHistoryButtons };
2026-02-04 23:31:53 +01:00
}