Skip to content

Commit

Permalink
Automatically opens categories when navigated to and scrolls them int…
Browse files Browse the repository at this point in the history
…o view
  • Loading branch information
martrapp committed Apr 12, 2024
1 parent 4999b08 commit f172816
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 136 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-zebras-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro-vtbot": patch
---

Improves sidebar handling: Automatically opens categories when navigated to and scrolls them into view.
56 changes: 34 additions & 22 deletions components/starlight/StarlightConnector.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ export interface Props {}
---

<script>
const STARLIGHT_MAIN_FRAME = 'div.main-frame';
const STARLIGHT_MAIN_SECTION = `${STARLIGHT_MAIN_FRAME} main`;
const STARLIGHT_MOBILE_MENU_EXPANDED = 'data-mobile-menu-expanded';
const STARLIGHT_SIDEBAR = 'nav.sidebar';
const STARLIGHT_MENU_BUTTON = 'starlight-menu-button';
const STARLIGHT_SIDEBAR_CONTENT = `${STARLIGHT_SIDEBAR} .sidebar-content`;
const REPLACE_SIDEBAR_CONTENT = 'vtbot-starlight-replace-sidebar-content';
import { sidebarEntry } from './utils';
import * as STARLIGHT from './utils';

export const REPLACE_SIDEBAR_CONTENT = 'vtbot-starlight-replace-sidebar-content';

openCurrentCategory();

function afterLoader(e: TransitionBeforePreparationEvent) {
markMainFrameForReplacementSwap(document);
Expand All @@ -21,14 +20,15 @@ export interface Props {}

function afterSwap(e: TransitionBeforeSwapEvent) {
updateSidebar(e);
openCurrentCategory();
}

/* ---------------- */

function closeMobileMenu() {
if (document.body.hasAttribute(STARLIGHT_MOBILE_MENU_EXPANDED)) {
if (document.body.hasAttribute(STARLIGHT.MOBILE_MENU_EXPANDED)) {
document.body
.querySelector(STARLIGHT_MENU_BUTTON)
.querySelector(STARLIGHT.MENU_BUTTON)
?.closest('nav')
?.dispatchEvent(
new KeyboardEvent('keyup', {
Expand All @@ -49,16 +49,14 @@ export interface Props {}
const replace = document.querySelector(`meta[name="${REPLACE_SIDEBAR_CONTENT}"]`);
if (replace) return;
document
.querySelectorAll('[aria-current="page"]')
.querySelectorAll(`${STARLIGHT.SIDEBAR_CONTENT} [aria-current="page"]`)
?.forEach((el) => el.removeAttribute('aria-current'));
const currentPage = document.querySelector(
`${STARLIGHT_SIDEBAR_CONTENT} a[href="${e.to.pathname}"]`
);
currentPage?.setAttribute('aria-current', 'page');

sidebarEntry(e.to)?.setAttribute('aria-current', 'page');
}

function markMainFrameForReplacementSwap(doc: Document) {
doc.body.querySelector(STARLIGHT_MAIN_FRAME)?.setAttribute('data-vtbot-replace', 'main');
doc.body.querySelector(STARLIGHT.MAIN_FRAME)?.setAttribute('data-vtbot-replace', 'main');
}

function setMainTransitionScope(e: TransitionBeforePreparationEvent) {
Expand All @@ -69,26 +67,26 @@ export interface Props {}
setMainTransitionScope(e.newDocument, mainTransitionScope);

function setMainTransitionScope(doc: Document, value: string) {
const main = doc.querySelector(STARLIGHT_MAIN_SECTION) as HTMLElement;
const main = doc.querySelector(STARLIGHT.MAIN_SECTION) as HTMLElement;
main && (main.dataset.astroTransitionScope = value);
}
}

function updateSidebar(e: TransitionBeforeSwapEvent) {
const replace = document.querySelector(`meta[name="${REPLACE_SIDEBAR_CONTENT}"]`);
const newSidebar = e.newDocument.querySelector(STARLIGHT_SIDEBAR);
const newSidebar = e.newDocument.querySelector(STARLIGHT.SIDEBAR);
if (!newSidebar) {
document.querySelector(STARLIGHT_SIDEBAR)?.remove();
document.querySelector(STARLIGHT.SIDEBAR)?.remove();
} else {
const sidebar = document.querySelector(STARLIGHT_SIDEBAR);
const sidebar = document.querySelector(STARLIGHT.SIDEBAR);
if (!sidebar) {
document
.querySelector(STARLIGHT_MAIN_FRAME)
.querySelector(STARLIGHT.MAIN_FRAME)
?.insertAdjacentElement('beforebegin', newSidebar);
} else {
if (replace) {
const oldContent = sidebar.querySelector(STARLIGHT_SIDEBAR_CONTENT);
const newContent = newSidebar.querySelector(STARLIGHT_SIDEBAR_CONTENT);
const oldContent = sidebar.querySelector(STARLIGHT.SIDEBAR_CONTENT);
const newContent = newSidebar.querySelector(STARLIGHT.SIDEBAR_CONTENT);
if (oldContent && newContent) {
oldContent.replaceWith(newContent);
} else {
Expand All @@ -99,6 +97,20 @@ export interface Props {}
}
}

function openCurrentCategory() {
const currentLink = document.querySelector(
`${STARLIGHT.SIDEBAR_CONTENT} [aria-current="page"]`
);
currentLink?.scrollIntoView({ block: 'center', behavior: 'instant'});
let category = currentLink?.closest('details');
while (category) {
category.open = true;
category = category.parentElement?.closest('details');
}
}

/*--------------------------*/

import {
TRANSITION_BEFORE_PREPARATION,
TRANSITION_BEFORE_SWAP,
Expand Down
Loading

0 comments on commit f172816

Please sign in to comment.