From 8fcc79738193fa142a7b4b67e1b4a0f0ecc46298 Mon Sep 17 00:00:00 2001 From: Nonimart Date: Tue, 24 Jun 2025 12:53:19 +0200 Subject: [PATCH] FEATURE Handling the different pannel behaviours --- resources/js/singles/index-panel.ts | 147 ++++++++++++++++++++++------ 1 file changed, 116 insertions(+), 31 deletions(-) diff --git a/resources/js/singles/index-panel.ts b/resources/js/singles/index-panel.ts index 342962d..4a6b473 100644 --- a/resources/js/singles/index-panel.ts +++ b/resources/js/singles/index-panel.ts @@ -1,10 +1,13 @@ -export default function handleIndexPanels(): void { +import { scrollToFootnote } from './footnote-format'; +import { handleSmoothScrollToTitle } from './sommaire'; + +export default function handleIndexPanel(): void { const indexPanel = document.querySelector('.index-panel'); if (!indexPanel) return; - console.log('indexPanel'); observeTabsButtons(); observeFootnotesLinks(); + observeSommaireLinks(); } // HANDLE TABS @@ -13,26 +16,19 @@ function observeTabsButtons(): void { buttons.forEach((button) => { button.addEventListener('click', () => { - toggleActiveTabsButton(button as HTMLElement); - toggleActiveTabsPanel(button as HTMLElement); + toggleActiveTabPanel(button.getAttribute('data-index') as string); }); }); } -function toggleActiveTabsButton(button: HTMLElement): void { - const buttons = document.querySelectorAll('.index-panel__header button'); - buttons.forEach((button) => { - button.setAttribute('aria-selected', 'false'); - }); - button.setAttribute('aria-selected', 'true'); -} - -function toggleActiveTabsPanel(activeButton: HTMLElement): void { - const dataIndex = activeButton.getAttribute('data-index'); +export function toggleActiveTabPanel(dataIndex: string): void { const activePanel = document.querySelector( `.index-panel__content > [data-index="${dataIndex}"]` ); - if (!dataIndex || !activePanel) return; + const activeButton = document.querySelector( + `.index-panel__header button[data-index="${dataIndex}"]` + ); + if (!dataIndex || !activePanel || !activeButton) return; // Hide all buttons and panels const allButtons = document.querySelectorAll('.index-panel__header button'); @@ -46,36 +42,125 @@ function toggleActiveTabsPanel(activeButton: HTMLElement): void { panel.setAttribute('aria-hidden', 'true'); }); - // Active the button and the panel activeButton.setAttribute('aria-selected', 'true'); activePanel.setAttribute('aria-hidden', 'false'); } -function observeFootnotesLinks(): void { - const footnotesButtons = document.querySelectorAll('.footnotes-index a'); +// ******************************************************** +// ************* SOMMAIRE ********************************* +// ******************************************************** - footnotesButtons.forEach((footnoteButton) => { - footnoteButton.addEventListener('click', (e) => { +function observeSommaireLinks(): void { + console.log('observeSommaireLinks'); + const sommaireTitles: NodeListOf = document.querySelectorAll('.sommaire-index li a'); + for (const title of sommaireTitles) { + title.addEventListener('click', (e) => { e.preventDefault(); - const target = e.target as HTMLElement; - const targetId = target.getAttribute('href'); + const href = title.getAttribute('href'); + if (!href) return; + + const targetId = href.startsWith('#') ? href.substring(1) : href; if (!targetId) return; - document.querySelector(targetId)?.scrollIntoView({ behavior: 'smooth' }); - toggleActiveFootnote(footnoteButton as HTMLElement); + handleSmoothScrollToTitle(targetId); + toggleActiveChapterLinkInIndexPanel(targetId); + }); + } +} + +function handleSmoothScrollToTitle(targetId: string): void { + const targetElement = document.querySelector(`#${targetId}`); + if (!targetElement) return; + + targetElement.scrollIntoView({ behavior: 'smooth' }); +} +function toggleActiveChapterLinkInIndexPanel(targetId: string): void { + const sommaireLinks: NodeListOf = document.querySelectorAll('.sommaire-index li a'); + + const indexPanel = document.querySelector('.index-panel') as HTMLElement; + const currentLink = indexPanel.querySelector(`a[href="#${targetId}"]`) as HTMLElement; + + console.log(currentLink); + + if (!currentLink) return; + + for (const link of sommaireLinks) { + link.setAttribute('active', 'false'); + } + + currentLink?.setAttribute('active', 'true'); +} + +// export function handleSmoothScrollToTitle(): void { +// const sommaireTitles: NodeListOf = document.querySelectorAll('.sommaire-index li a'); +// for (const title of sommaireTitles) { +// title.addEventListener('click', (e) => { +// e.preventDefault(); + +// const target = title.getAttribute('href'); +// if (!target) return; + +// const targetElement = document.querySelector(target); +// if (!targetElement) return; + +// targetElement.scrollIntoView({ behavior: 'smooth' }); +// }); +// } +// } + +// ******************************************************** +// ************* FOOTNOTES ********************************* +// ******************************************************** + +function observeFootnotesLinks(): void { + const footnotesLinks = document.querySelectorAll('.footnotes-index a'); + + footnotesLinks.forEach((footnoteLink) => { + footnoteLink.addEventListener('click', (e) => { + e.preventDefault(); + const target = e.target as HTMLElement; + const href = target.getAttribute('href'); + if (!href) return; + + const targetId = href.startsWith('#') ? href.substring(1) : href; + if (!targetId) return; + scrollToFootnote(targetId); + // document.querySelector(`#${targetId}`)?.scrollIntoView({ behavior: 'smooth' }); + + toggleActiveFootnoteLinkInIndexPanel(targetId); + scrollToFootnoteInIndexPanel(targetId); }); }); } -function toggleActiveFootnote(button: HTMLElement): void { - const buttons = document.querySelectorAll('footnote-reference-item'); +export function toggleActiveFootnoteLinkInIndexPanel(footnoteId: string): void { + const footnotesIndexLinks = document.querySelectorAll('.footnote-reference-item'); + const indexPanel = document.querySelector('.index-panel') as HTMLElement; + const currentFootnote = indexPanel.querySelector(`a[href="#${footnoteId}"]`) as HTMLElement; - const footnotesItems = document.querySelectorAll('.footnote-reference-item'); - - footnotesItems.forEach((footnoteItem) => { - footnoteItem.setAttribute('active', 'false'); + footnotesIndexLinks.forEach((footnoteLink) => { + footnoteLink.setAttribute('active', 'false'); }); - button.setAttribute('active', 'true'); + currentFootnote?.setAttribute('active', 'true'); +} + +export function scrollToFootnoteInIndexPanel(footnoteId: string): void { + const footnotesIndex = document.querySelector('#footnotes-index') as HTMLElement; + const indexPanel = document.querySelector('.index-panel') as HTMLElement; + const currentFootnote = indexPanel?.querySelector(`a[href="#${footnoteId}"]`) as HTMLElement; + + if (currentFootnote && indexPanel) { + const containerRect = indexPanel.getBoundingClientRect(); + const elementRect = currentFootnote.getBoundingClientRect(); + + const relativeTop = elementRect.top - containerRect.top; + const scrollTop = indexPanel.scrollTop + relativeTop - 20; + + indexPanel.scrollTo({ + top: scrollTop, + behavior: 'smooth', + }); + } }