Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/site/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const config = {

clientModules: [
"./src/client/webmcp.js",
"./src/client/kapa-sidebar.js",
],

onBrokenLinks: "throw",
Expand Down Expand Up @@ -297,6 +298,9 @@ const config = {
"data-project-name": "Walrus Knowledge",
"data-project-color": "#37c3b0ff",
"data-button-hide": "true",
"data-view-mode": "sidebar",
"data-modal-overlay-hidden": "true",
"data-modal-lock-scroll": "false",
"data-modal-title": "Ask Walrus AI",
"data-modal-ask-ai-input-placeholder": "Ask me anything about Walrus!",
"data-modal-example-questions":
Expand Down Expand Up @@ -344,6 +348,7 @@ const config = {
label: "Service Providers",
position: "right",
},
{ to: "/skills", label: "Skills", position: "right" },
{ to: "/blog", label: "Blog", position: "right" },
{
href: "https://github.com/MystenLabs/walrus",
Expand Down
2 changes: 1 addition & 1 deletion docs/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"deploy-site": "site-builder deploy ./build --epochs 1",
"docusaurus": "docusaurus",
"prestart": "node src/scripts/prepare-walrus-memory.js && node src/scripts/generate-import-context.js && node src/scripts/copy-yaml-files.js",
"prestart": "node src/scripts/generate-skills.mjs && node src/scripts/prepare-walrus-memory.js && node src/scripts/generate-import-context.js && node src/scripts/copy-yaml-files.js",
"start": "docusaurus start",
"prebuild": "FORCE_FETCH=1 npm run prestart",
"build:prep": "node src/shared/js/inline-imports.js && node src/scripts/copy-markdown-files.js && node src/scripts/generate-llmstxt.mjs",
Expand Down
85 changes: 85 additions & 0 deletions docs/site/src/client/kapa-sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) Walrus Foundation
// SPDX-License-Identifier: Apache-2.0

// Detects Kapa sidebar open/close and toggles .kapa-sidebar-open on <html>.
// Kapa renders in Shadow DOM so we can't query its internals.
// Strategy: hook Kapa.open for instant open detection, then use
// elementFromPoint to detect close (checks if right edge of screen
// is covered by a non-docusaurus element).

if (typeof window !== "undefined") {
const OPEN_CLASS = "kapa-sidebar-open";
let kapaOpen = false;
let hookedRef = null;

function syncClass() {
document.documentElement.classList.toggle(OPEN_CLASS, kapaOpen);
}

function hookKapa() {
if (!window.Kapa || !window.Kapa.open || window.Kapa.open === hookedRef)
return;

const origOpen = window.Kapa.open;
const origClose = window.Kapa.close;

window.Kapa.open = function (...args) {
kapaOpen = true;
syncClass();
return origOpen.apply(this, args);
};

window.Kapa.close = function (...args) {
kapaOpen = false;
syncClass();
return origClose.apply(this, args);
};

hookedRef = window.Kapa.open;
}

// Check if Kapa sidebar is covering the right side of the viewport.
// Since Kapa uses Shadow DOM, we can't query its elements directly.
// Instead, check if the element at the right edge of the screen
// belongs to the doc app or to something else (Kapa's panel).
function isSidebarVisible() {
const x = window.innerWidth - 50;
const y = window.innerHeight / 2;
const el = document.elementFromPoint(x, y);
if (!el) return false;
const docRoot = document.getElementById("__docusaurus");
if (docRoot && docRoot.contains(el)) return false;
if (el === document.body || el === document.documentElement) return false;
return true;
}

// Hook into History API so the class persists across SPA navigation.
// Docusaurus uses pushState for client-side routing.
const origPush = history.pushState.bind(history);
const origReplace = history.replaceState.bind(history);
history.pushState = function (...args) {
const r = origPush(...args);
syncClass();
return r;
};
history.replaceState = function (...args) {
const r = origReplace(...args);
syncClass();
return r;
};
window.addEventListener("popstate", syncClass);

// Poll every 300ms: re-hook Kapa if it reinitializes, and
// detect open/close state via elementFromPoint fallback.
setInterval(() => {
hookKapa();

const visible = isSidebarVisible();
if (visible && !kapaOpen) {
kapaOpen = true;
} else if (!visible && kapaOpen) {
kapaOpen = false;
}
syncClass();
}, 300);
}
Loading
Loading