From 27357e5c3c0da8c31dab627d5305fdf08fbdbb3b Mon Sep 17 00:00:00 2001 From: Nonimart Date: Mon, 23 Jun 2025 16:17:11 +0200 Subject: [PATCH] FEATURE Introducing panel behaviour handling --- resources/js/singles/index-panel.ts | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 resources/js/singles/index-panel.ts diff --git a/resources/js/singles/index-panel.ts b/resources/js/singles/index-panel.ts new file mode 100644 index 0000000..64d8e71 --- /dev/null +++ b/resources/js/singles/index-panel.ts @@ -0,0 +1,80 @@ +export default function handleIndexPanels(): void { + const indexPanel = document.querySelector('.index-panel'); + if (!indexPanel) return; + + observeTabsButtons(); + observeFootnotesLinks(); +} + +// HANDLE TABS +function observeTabsButtons(): void { + const buttons = document.querySelectorAll('.index-panel__header button'); + + buttons.forEach((button) => { + button.addEventListener('click', () => { + toggleActiveTabsButton(button as HTMLElement); + toggleActiveTabsPanel(button as HTMLElement); + }); + }); +} + +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'); + const activePanel = document.querySelector( + `.index-panel__content > [data-index="${dataIndex}"]` + ); + if (!dataIndex || !activePanel) return; + + // Hide all buttons and panels + const allButtons = document.querySelectorAll('.index-panel__header button'); + const allPanels = document.querySelectorAll('.index-panel__content > [data-index]'); + + allButtons.forEach((button) => { + button.setAttribute('aria-selected', 'false'); + }); + + allPanels.forEach((panel) => { + 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'); + + footnotesButtons.forEach((footnoteButton) => { + footnoteButton.addEventListener('click', (e) => { + e.preventDefault(); + const target = e.target as HTMLElement; + const targetId = target.getAttribute('href'); + + if (!targetId) return; + + document.querySelector(targetId)?.scrollIntoView({ behavior: 'smooth' }); + toggleActiveFootnote(footnoteButton as HTMLElement); + }); + }); +} + +function toggleActiveFootnote(button: HTMLElement): void { + const buttons = document.querySelectorAll('footnote-reference-item'); + + const footnotesItems = document.querySelectorAll('.footnote-reference-item'); + + footnotesItems.forEach((footnoteItem) => { + footnoteItem.setAttribute('active', 'false'); + }); + + button.setAttribute('active', 'true'); +}