import * as React from "react"; import styled from "styled-components"; import { useThemeConfig } from "@theme/hooks/useThemeConfig"; import { LanguagePicker } from "@theme/i18n/LanguagePicker"; import { useI18n, useTranslate } from "@portal/hooks"; import { slugify } from "../../helpers"; import { Link } from "@portal/Link"; import { ColorModeSwitcher } from "@theme/components/ColorModeSwitcher/ColorModeSwitcher"; import { Search } from "@theme/components/Search/Search"; import { useLocation } from "react-router-dom"; // @ts-ignore // import navbar from '../../../top-nav.yaml'; const alertBanner = { show: true, message: "XRP Ledger Apex is back in Amsterdam", button: "Register Now", link: "https://www.xrpledgerapex.com/?utm_source=xrplorg&utm_medium=web&utm_campaign=banner", }; export function Navbar(props) { // const [isOpen, setIsOpen] = useMobileMenu(false); const themeConfig = useThemeConfig(); const { changeLanguage } = useI18n(); const menu = themeConfig.navbar?.items; const logo = themeConfig.logo; const { href, altText, items } = props; const pathPrefix = ""; const navItems = menu.map((item, index) => { if (item.type === "group") { return ( ); } else { return ( {item.label} ); } }); const { pathname } = useLocation(); const blogNavs = getBlogNavigationConfig(); const blogNavItems = []; for (const blogNav of blogNavs) { if (blogNav.type === "group") { blogNavItems.push( ); } else { blogNavItems.push( {blogNav.label} ); } } React.useEffect(() => { // Turns out jQuery is necessary for firing events on Bootstrap v4 // dropdowns. These events set classes so that the search bar and other // submenus collapse on mobile when you expand one submenu. const dds = $("#topnav-pages .dropdown"); const top_main_nav = document.querySelector("#top-main-nav"); dds.on("show.bs.dropdown", (evt) => { top_main_nav.classList.add("submenu-expanded"); }); dds.on("hidden.bs.dropdown", (evt) => { top_main_nav.classList.remove("submenu-expanded"); }); // Close navbar on .dropdown-item click const toggleNavbar = () => { const navbarToggler = document.querySelector(".navbar-toggler"); const isNavbarCollapsed = navbarToggler.getAttribute("aria-expanded") === "true"; if (isNavbarCollapsed) { navbarToggler.click(); // Simulate click to toggle navbar } }; const dropdownItems = document.querySelectorAll(".dropdown-item"); dropdownItems.forEach((item) => { item.addEventListener("click", toggleNavbar); }); // Cleanup function to remove event listeners return () => { dropdownItems.forEach((item) => { item.removeEventListener("click", toggleNavbar); }); }; }, []); // Render a different top nav for the Blog site. if (pathname.includes("blog")) { return ( <> {blogNavItems}
); } else { return ( <> {navItems}
); } } const StyledColorModeSwitcher = styled(ColorModeSwitcher)` padding: 10px; `; export function AlertBanner(props) { const { message, button, link } = props; return (

{message}

{button}
); } export function TopNavCollapsible(props) { return (
{props.children}
); } export function NavDropdown(props) { const { label, items, pathPrefix, labelTranslationKey } = props; const { translate } = useTranslate(); const dropdownGroups = items.map((item, index) => { if (item.items) { const groupLinks = item.items.map((item2, index2) => { const cls2 = item2.external ? "dropdown-item external-link" : "dropdown-item"; let item2_href = item2.link; if (item2_href && !item2_href.match(/^https?:/)) { item2_href = pathPrefix + item2_href; } return ( {item2.label} ); }); const clnm = "navcol col-for-" + slugify(item.label); return (
{item.label}
{groupLinks}
); } else if (item.icon) { const hero_id = "dropdown-hero-for-" + slugify(label); const img_alt = item.label + " icon"; let hero_href = item.link; if (hero_href && !hero_href.match(/^https?:/)) { hero_href = pathPrefix + hero_href; } const splitlabel = item.label.split(" || "); const newlabel = splitlabel[0]; const description = splitlabel[1]; // might be undefined, that's ok return ( {img_alt}

{newlabel}

{description}

); } else { const cls = item.external ? "dropdown-item ungrouped external-link" : "dropdown-item ungrouped"; let item_href = item.link; if (item_href && !item_href.match(/^https?:/)) { item_href = pathPrefix + item_href; } return ( {item.label} ); } }); const toggler_id = "topnav_" + slugify(label); const dd_id = "topnav_dd_" + slugify(label); return (
  • {dropdownGroups}
  • ); } export function NavWrapper(props) { return ( ); } export function NavControls(props) { return ( ); } export function MobileMenuIcon() { return (
    ); } export function GetStartedButton() { const { translate } = useTranslate(); return ( {translate("Get Started")} ); } export function NavItems(props) { return (
      {props.children}
    ); } export function NavItem(props) { return
  • {props.children}
  • ; } export function LogoBlock(props) { const { to, img, altText } = props; return ( {"XRP ); } export class ThemeToggle extends React.Component { auto_update_theme() { const upc = window.localStorage.getItem("user-prefers-color"); let theme = "dark"; // Default to dark theme if (!upc) { // User hasn't saved a preference specifically for this site; check // the browser-level preferences. if ( window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches ) { theme = "light"; } } else { // Follow user's saved setting. theme = upc == "light" ? "light" : "dark"; } const disable_theme = theme == "dark" ? "light" : "dark"; document.documentElement.classList.add(theme); document.documentElement.classList.remove(disable_theme); } user_choose_theme() { const new_theme = document.documentElement.classList.contains("dark") ? "light" : "dark"; window.localStorage.setItem("user-prefers-color", new_theme); document.body.style.transition = "background-color .2s ease"; const disable_theme = new_theme == "dark" ? "light" : "dark"; document.documentElement.classList.add(new_theme); document.documentElement.classList.remove(disable_theme); } render() { return (
    ); } componentDidMount() { this.auto_update_theme(); } } function getBlogNavigationConfig() { const { translate } = useTranslate(); return [ { index: "0", label: translate("Learn"), type: "group", items: [ { type: "group", label: translate("XRP Ledger"), items: [ { type: "link", fsPath: "about/index.page.tsx", label: translate("Overview"), link: "/about/", }, { type: "link", fsPath: "about/uses.page.tsx", label: translate("Uses"), link: "/about/uses", }, { type: "link", fsPath: "about/history.page.tsx", label: translate("History"), link: "/about/history", }, { type: "link", fsPath: "about/impact.page.tsx", label: translate("Impact"), link: "/about/impact", }, { type: "link", fsPath: "about/impact.page.tsx", label: translate("Carbon Calculator"), link: "/about/impact", }, ], }, ], pathPrefix: "", }, { index: "1", label: translate("Explore"), type: "group", items: [ { type: "group", label: translate("Explore the XRP Ledger"), items: [ { type: "link", fsPath: "/docs/introduction/crypto-wallets.md", label: translate("Wallets"), link: "/docs/introduction/crypto-wallets", }, { type: "link", fsPath: "about/xrp.page.tsx", label: translate("Exchanges"), link: "/about/xrp", }, { type: "link", fsPath: "about/uses.page.tsx", label: translate("Businesses"), link: "/about/uses", }, { type: "link", fsPath: "", label: translate("Ledger Explorer"), link: "https://livenet.xrpl.org/", }, ], }, ], pathPrefix: "", }, { index: "2", label: translate("Build"), type: "group", items: [ { type: "group", label: translate("Build with XRPL"), items: [ { type: "link", fsPath: "/docs/index.page.tsx", label: translate("Docs"), link: "/docs/", }, { type: "link", fsPath: "/resources/dev-tools/index.page.tsx", label: translate("Dev Tools"), link: "/resources/dev-tools/", }, { type: "link", fsPath: "/blog/index.page.tsx", label: translate("Dev Blog"), link: "/blog/", }, ], }, ], pathPrefix: "", }, { index: "3", type: "link", fsPath: "community/index.page.tsx", label: translate("Contribute"), link: "/community", }, ]; }