+Startseite u. Suche Baic styling

This commit is contained in:
Simon Martens
2025-09-29 18:29:17 +02:00
parent 0d7886a664
commit 52758c0124
16 changed files with 669 additions and 361 deletions

View File

@@ -19,11 +19,15 @@ export class InhaltsverzeichnisScrollspy extends HTMLElement {
this.singlePageViewerActive = false;
this.singlePageViewerCurrentPage = null; // Track which page is currently viewed in single page mode
this.boundHandleSinglePageViewer = this.handleSinglePageViewer.bind(this);
this.eventListenersAttached = false; // Track if global event listeners are attached
}
connectedCallback() {
this.setupScrollspy();
this.setupSinglePageViewerDetection();
// Use requestAnimationFrame to ensure DOM is fully settled after HTMX content swap
requestAnimationFrame(() => {
this.setupScrollspy();
this.setupSinglePageViewerDetection();
});
}
disconnectedCallback() {
@@ -35,9 +39,27 @@ export class InhaltsverzeichnisScrollspy extends HTMLElement {
const newspaperPageContainers = document.querySelectorAll('.newspaper-page-container[data-page-container]');
if (newspaperPageContainers.length === 0) {
return; // No page containers found
// No page containers found initially - retry after a short delay for HTMX content
setTimeout(() => {
const retryContainers = document.querySelectorAll('.newspaper-page-container[data-page-container]');
if (retryContainers.length > 0) {
this.initializeScrollspy(retryContainers);
}
}, 100);
return;
}
this.initializeScrollspy(newspaperPageContainers);
}
initializeScrollspy(newspaperPageContainers) {
// Clear existing state to prevent conflicts during HTMX navigation
if (this.pageObserver) {
this.pageObserver.disconnect();
}
this.pageContainers.clear();
// Map page containers to their corresponding Inhaltsverzeichnis entries
newspaperPageContainers.forEach(container => {
const pageNumber = container.getAttribute('data-page-container');
@@ -236,10 +258,13 @@ export class InhaltsverzeichnisScrollspy extends HTMLElement {
}
setupSinglePageViewerDetection() {
// Listen for single page viewer events
document.addEventListener('singlepageviewer:opened', this.boundHandleSinglePageViewer);
document.addEventListener('singlepageviewer:closed', this.boundHandleSinglePageViewer);
document.addEventListener('singlepageviewer:pagechanged', this.boundHandleSinglePageViewer);
// Only attach event listeners if not already attached
if (!this.eventListenersAttached) {
document.addEventListener('singlepageviewer:opened', this.boundHandleSinglePageViewer);
document.addEventListener('singlepageviewer:closed', this.boundHandleSinglePageViewer);
document.addEventListener('singlepageviewer:pagechanged', this.boundHandleSinglePageViewer);
this.eventListenersAttached = true;
}
// Check initial state
this.checkSinglePageViewerState();
@@ -302,9 +327,13 @@ export class InhaltsverzeichnisScrollspy extends HTMLElement {
this.pageObserver = null;
}
document.removeEventListener('singlepageviewer:opened', this.boundHandleSinglePageViewer);
document.removeEventListener('singlepageviewer:closed', this.boundHandleSinglePageViewer);
document.removeEventListener('singlepageviewer:pagechanged', this.boundHandleSinglePageViewer);
// Only remove event listeners if they were attached
if (this.eventListenersAttached) {
document.removeEventListener('singlepageviewer:opened', this.boundHandleSinglePageViewer);
document.removeEventListener('singlepageviewer:closed', this.boundHandleSinglePageViewer);
document.removeEventListener('singlepageviewer:pagechanged', this.boundHandleSinglePageViewer);
this.eventListenersAttached = false;
}
this.pageContainers.clear();
}

View File

@@ -140,7 +140,6 @@ export class PlaceAccordion extends HTMLElement {
connectedCallback() {
this.setupAccordion();
this.setupEventListeners();
this.updateBorders();
this.setupMapEventListeners();
this.setupHoverEvents();
}
@@ -160,26 +159,12 @@ export class PlaceAccordion extends HTMLElement {
}
setupAccordion() {
// Add chevron icon if not already present
if (!this.querySelector(".accordion-chevron")) {
const chevron = document.createElement("i");
chevron.className =
"ri-chevron-down-line accordion-chevron transition-transform duration-200 text-slate-400";
// Find the badge and insert chevron before it
const badge = this.querySelector('[class*="bg-slate-100"]');
if (badge) {
badge.parentNode.insertBefore(chevron, badge);
}
}
// Create content container if not exists
if (!this.querySelector("[data-content]")) {
const placeId = this.getAttribute("data-place-id");
const contentContainer = document.createElement("div");
contentContainer.setAttribute("data-content", "");
contentContainer.className =
"accordion-content overflow-hidden transition-all duration-300 max-h-0";
"accordion-content overflow-hidden transition-all duration-300 max-h-0 border-b border-slate-200";
// Add HTMX attributes to override body defaults
contentContainer.setAttribute("hx-get", `/ort/fragment/${placeId}`);
@@ -272,8 +257,6 @@ export class PlaceAccordion extends HTMLElement {
if (this.isLoading) return;
this.isExpanded = true;
this.updateChevron();
this.updateBorders();
const contentContainer = this.querySelector("[data-content]");
if (!contentContainer) return;
@@ -289,8 +272,6 @@ export class PlaceAccordion extends HTMLElement {
collapse() {
this.isExpanded = false;
this.updateChevron();
this.updateBorders();
const contentContainer = this.querySelector("[data-content]");
if (contentContainer) {
@@ -330,33 +311,6 @@ export class PlaceAccordion extends HTMLElement {
// Trigger the HTMX request
htmx.trigger(contentContainer, "load-content");
}
updateChevron() {
const chevron = this.querySelector(".accordion-chevron");
if (chevron) {
if (this.isExpanded) {
chevron.style.transform = "rotate(180deg)";
} else {
chevron.style.transform = "rotate(0deg)";
}
}
}
updateBorders() {
if (this.isExpanded) {
// When expanded: remove border from header, add border to whole component
this.classList.add("border-b", "border-slate-100");
} else {
// When collapsed: add border to component (for separation between items)
this.classList.add("border-b", "border-slate-100");
}
// Remove border from last item if it's the last child
const isLastChild = !this.nextElementSibling;
if (isLastChild) {
this.classList.remove("border-b");
}
}
}
/**
@@ -525,7 +479,8 @@ export class PlacesMap extends HTMLElement {
circle.setAttribute("filter", "drop-shadow(0 0.05 0.08 rgba(0,0,0,0.15))");
circle.style.cursor = "pointer";
circle.style.pointerEvents = "all";
circle.style.transition = "r 0.3s ease, fill 0.3s ease, stroke 0.3s ease, opacity 0.3s ease";
circle.style.transition =
"r 0.3s ease, fill 0.3s ease, stroke 0.3s ease, opacity 0.3s ease";
// Add hover effects for white dots
circle.addEventListener("mouseenter", () => {
@@ -664,7 +619,6 @@ export class PlacesMap extends HTMLElement {
placeContainers.forEach((container) => {
this.intersectionObserver.observe(container);
});
}
setPointActive(circle) {
@@ -701,7 +655,6 @@ export class PlacesMap extends HTMLElement {
return;
}
if (this.tooltip && tooltipText) {
// Set tooltip content and position
this.tooltip.textContent = tooltipText;

View File

@@ -418,7 +418,7 @@ class SchnellauswahlButton extends HTMLElement {
this.innerHTML = `
<button
id="filter-toggle"
class="mr-2 text-lg border px-4 h-full hover:bg-slate-200 transition-colors cursor-pointer"
class="mr-2 text-lg border px-4 h-full bg-white hover:bg-slate-200 transition-colors cursor-pointer"
title="Schnellfilter öffnen/schließen">
<i class="ri-filter-2-line"></i> <div class="inline-block text-lg">Schnellauswahl</div>
</button>
@@ -543,36 +543,36 @@ class NavigationMenu extends HTMLElement {
}
static get observedAttributes() {
return ['git-commit', 'git-date', 'git-url'];
return ["git-commit", "git-date", "git-url"];
}
get gitCommit() {
return this.getAttribute('git-commit');
return this.getAttribute("git-commit");
}
get gitDate() {
return this.getAttribute('git-date');
return this.getAttribute("git-date");
}
get gitUrl() {
return this.getAttribute('git-url');
return this.getAttribute("git-url");
}
formatCommitInfo() {
if (!this.gitCommit) {
return 'Keine Commit-Info';
return "Keine Commit-Info";
}
const shortCommit = this.gitCommit.substring(0, 7);
if (this.gitDate) {
const date = new Date(this.gitDate);
const formattedDate = date.toLocaleDateString('de-DE', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
const formattedDate = date.toLocaleDateString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
return `${shortCommit} (${formattedDate})`;
return `${shortCommit} - ${formattedDate}`;
}
return shortCommit;
@@ -590,35 +590,35 @@ class NavigationMenu extends HTMLElement {
createMenu() {
this.innerHTML = `
<div>
<div class="h-full relative">
<button
class="ml-2 text-2xl border px-4 h-full hover:bg-slate-200 transition-colors cursor-pointer"
class="ml-2 text-2xl border px-4 h-full bg-white hover:bg-slate-200 transition-colors cursor-pointer"
id="menu-toggle">
<i class="ri-menu-line"></i>
</button>
<div id="menu-dropdown" class="hidden absolute bg-slate-50 px-5 py-3 z-50">
<div>
<div>Übersicht nach</div>
<div class="ml-2 flex flex-col gap-y-2 mt-2">
<div id="menu-dropdown" class="hidden absolute bg-white py-2 z-50 top-[115%] right-0 shadow-sm">
<div class="px-5">
<div class="whitespace-nowrap">Übersicht nach</div>
<div class="ml-2 flex flex-col gap-y-2 mt-2 whitespace-nowrap">
<a href="/">Jahrgängen</a>
<a href="/akteure/a">Personen &amp; Werke</a>
<a href="/akteure/a">Personen &amp; Werken</a>
<a href="/kategorie/">Betragsarten</a>
<a href="/ort/">Orten</a>
</div>
</div>
<div class="border-t border-slate-300 pt-2 mt-2">
<div class="border-t border-slate-300 pt-2 mt-2 px-5">
<div class="flex flex-col gap-y-2">
<a href="/edition/">Geschichte & Edition der KGPZ</a>
<a href="/zitation/">Zitation</a>
<a href="/kontakt/">Kontakt</a>
</div>
<div class="mt-3 pt-2 border-t border-slate-200 text-xs text-slate-600">
<a href="${this.gitUrl || 'https://github.com/Theodor-Springmann-Stiftung/KGPZ.git'}" target="_blank" class="flex items-center gap-1 hover:text-slate-800">
<i class="ri-git-branch-line"></i>
<span>${this.formatCommitInfo()}</span>
</a>
</div>
</div>
<div class="mt-3 pt-2 border-t border-slate-200 text-xs text-slate-600 px-2 text-centeer vertical-align-middle">
<i class="ri-git-branch-line"></i>
<a href="${this.gitUrl || "https://github.com/Theodor-Springmann-Stiftung/KGPZ.git"}" target="_blank" class="hover:text-slate-800">
<span>Commit ${this.formatCommitInfo()}</span>
</a>
</div>
</div>
</div>
`;
@@ -721,23 +721,36 @@ customElements.define("navigation-menu", NavigationMenu);
/**
* Global event handler for quickfilter selections
* Dispatches custom events when users select persons or places from quickfilter
* Dispatches custom events when users select persons, places, or categories from quickfilter
*/
document.addEventListener("DOMContentLoaded", function () {
// Add event delegation for person and place links in quickfilter
// Add event delegation for person, place, and category links in quickfilter
document.addEventListener("click", function (event) {
// Check if the clicked element is a person or place link within the quickfilter
const quickfilterTarget = event.target.closest('a[href^="/akteure/"], a[href^="/ort/"]');
// Check if the clicked element is a person, place, or category link within the quickfilter
const quickfilterTarget = event.target.closest(
'a[href^="/akteure/"], a[href^="/ort/"], a[href^="/kategorie/"]',
);
const filterContainer = document.getElementById("filter-container");
if (quickfilterTarget && filterContainer && filterContainer.contains(quickfilterTarget)) {
// Determine the type based on the URL
let type;
const href = quickfilterTarget.getAttribute("href");
if (href.startsWith("/akteure/")) {
type = "person";
} else if (href.startsWith("/ort/")) {
type = "place";
} else if (href.startsWith("/kategorie/")) {
type = "category";
}
// Dispatch custom event to notify components
const selectionEvent = new CustomEvent("quickfilter:selection", {
detail: {
type: quickfilterTarget.getAttribute("href").startsWith("/akteure/") ? "person" : "place",
type: type,
source: "quickfilter",
id: quickfilterTarget.getAttribute("href").split("/").pop(),
url: quickfilterTarget.getAttribute("href"),
id: href.split("/").pop(),
url: href,
},
bubbles: true,
});