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
30 changes: 30 additions & 0 deletions src/components/Common/SectionNavLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import clsx from "clsx";
import Link from "@docusaurus/Link";
import { Icon } from "@site/src/components/Common/Icon";
import type { SectionNavItem } from "@site/src/typescript/pathUtils";

interface SectionNavLinkProps {
item: SectionNavItem;
isActive: boolean;
onClick?: () => void;
}

export function SectionNavLink({ item, isActive, onClick }: SectionNavLinkProps) {
return (
<Link
to={item.to}
onClick={onClick}
// Not "page": the entry points at the section landing page, which is rarely the page you are on.
aria-current={isActive ? "true" : undefined}
className={clsx(
"menu__link",
isActive && "!bg-black/5 !font-semibold hover:!bg-black/10 dark:!bg-white/5 dark:hover:!bg-white/10"
)}
>
<Icon icon={item.icon} size="xs" className="me-2" />
{item.label}
{item.external && <Icon icon="newtab" size="xs" className="ms-auto opacity-60" />}
</Link>
);
}
65 changes: 8 additions & 57 deletions src/theme/DocSidebar/Desktop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import SidebarVersionDropdown from "@site/src/components/SidebarVersionDropdown"

import { useActiveDocContext, useLatestVersion } from "@docusaurus/plugin-content-docs/client";
import { Icon } from "@site/src/components/Common/Icon";
import { getPathType, getLandingPagePath, PathType } from "../../../typescript/pathUtils";
import { SectionNavLink } from "@site/src/components/Common/SectionNavLink";
import { getPathType, getSectionNavItems, PathType } from "../../../typescript/pathUtils";

function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
const {
Expand All @@ -28,7 +29,7 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
const versionLabel = activeVersion?.label ?? latestVersion.label;

const pathType = getPathType(path);
const landingPagePath = getLandingPagePath(pathType, versionLabel);
const sectionNavItems = getSectionNavItems(pathType, versionLabel);

const shouldDisplayContent = pathType !== PathType.Guides && pathType !== PathType.Samples;

Expand All @@ -41,66 +42,16 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
)}
>
{hideOnScroll && <Logo tabIndex={-1} className={styles.sidebarLogo} />}
<div className="menu thin-scrollbar menu_Y1UP shrink-0 !grow-0">
<div className="menu__list-item-collapsible">
<Link to={landingPagePath} className="menu__link">
<Icon icon="home" size="xs" className="me-2" /> Start
</Link>
</div>
{pathType !== PathType.Guides && (
<Link to="/guides" className="menu__link group">
<Icon icon="guides" size="xs" className="me-2" /> Guides
<small className="flex items-center ms-auto gap-1 text-[0.675rem] opacity-0 group-hover:opacity-100 !transition-all">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Samples && (
<Link to="/samples" className="menu__link group">
<Icon icon="create-sample-data" size="xs" className="me-2" /> Samples
<small className="flex items-center ms-auto gap-1 text-[0.675rem] opacity-0 group-hover:opacity-100 !transition-all">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Documentation && (
<Link to={`/${versionLabel}`} className="menu__link group">
<Icon icon="database" size="xs" className="me-2" /> RavenDB Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem] opacity-0 group-hover:opacity-100 !transition-all">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Cloud && (
<Link to="/cloud" className="menu__link group">
<Icon icon="cloud" size="xs" className="me-2" /> RavenDB Cloud Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem] opacity-0 group-hover:opacity-100 !transition-all">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Quill && (
<Link to="/quill" className="menu__link group">
<Icon icon="quill" size="xs" className="me-2" /> Quill Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem] opacity-0 group-hover:opacity-100 !transition-all">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
<Link to="https://ravendb.net/community" className="menu__link group">
<Icon icon="community" size="xs" className="me-2" /> Community
<Icon
icon="newtab"
size="xs"
className="ms-auto opacity-0 group-hover:opacity-100 !transition-all"
/>
</Link>
<nav aria-label="Documentation sections" className="menu thin-scrollbar menu_Y1UP shrink-0 !grow-0">
{sectionNavItems.map((item) => (
<SectionNavLink key={item.label} item={item} isActive={item.pathType === pathType} />
))}
{pathType === PathType.Documentation && (
<Link to={`/${versionLabel}/whats-new`} className="menu__link">
<Icon icon="star-filled" size="xs" className="me-2" /> What's new
</Link>
)}
</div>
</nav>
{shouldDisplayContent && <hr className="!my-0 !mx-3 !bg-black/10 dark:!bg-white/10" />}
{pathType === PathType.Documentation && <SidebarVersionDropdown />}
{shouldDisplayContent && <Content path={path} sidebar={sidebar} />}
Expand Down
65 changes: 12 additions & 53 deletions src/theme/DocSidebar/Mobile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import type { Props } from "@theme/DocSidebar/Mobile";
import Link from "@docusaurus/Link";
import { useActiveDocContext, useLatestVersion } from "@docusaurus/plugin-content-docs/client";
import { Icon } from "@site/src/components/Common/Icon";
import { SectionNavLink } from "@site/src/components/Common/SectionNavLink";
import type { Props as DocSidebarProps } from "@theme/DocSidebar";
import SidebarVersionDropdown from "@site/src/components/SidebarVersionDropdown";
import { getPathType, getLandingPagePath, PathType } from "../../../typescript/pathUtils";
import { getPathType, getSectionNavItems, PathType } from "../../../typescript/pathUtils";

function DocSidebarMobileSecondaryMenu({ sidebar, path }: DocSidebarProps) {
const mobileSidebar = useNavbarMobileSidebar();
Expand All @@ -20,63 +21,21 @@ function DocSidebarMobileSecondaryMenu({ sidebar, path }: DocSidebarProps) {
const versionLabel = activeVersion?.label ?? latestVersion.label;

const pathType = getPathType(path);
const landingPagePath = getLandingPagePath(pathType, versionLabel);
const sectionNavItems = getSectionNavItems(pathType, versionLabel);

const shouldDisplayContent = pathType !== PathType.Guides && pathType !== PathType.Samples;

return (
<ul className={clsx(ThemeClassNames.docs.docSidebarMenu, "menu__list")}>
<li className="menu__list-item">
<div className="menu__list-item-collapsible">
<Link to={landingPagePath} className="menu__link" onClick={() => mobileSidebar.toggle()}>
<Icon icon="home" size="xs" className="me-2" /> Start
</Link>
</div>
</li>
{pathType !== PathType.Guides && (
<Link to="/guides" className="menu__link group">
<Icon icon="guides" size="xs" className="me-2" /> Guides
<small className="flex items-center ms-auto gap-1 text-[0.675rem]">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Documentation && (
<Link to={`/${versionLabel}`} className="menu__link group">
<Icon icon="database" size="xs" className="me-2" /> RavenDB Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem]">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Samples && (
<Link to="/samples" className="menu__link group">
<Icon icon="create-sample-data" size="xs" className="me-2" /> Samples
<small className="flex items-center ms-auto gap-1 text-[0.675rem]">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Cloud && (
<Link to="/cloud" className="menu__link group">
<Icon icon="cloud" size="xs" className="me-2" /> RavenDB Cloud Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem]">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
{pathType !== PathType.Quill && (
<Link to="/quill" className="menu__link group">
<Icon icon="sparkles" size="xs" className="me-2" /> Quill Docs
<small className="flex items-center ms-auto gap-1 text-[0.675rem]">
Switch <Icon icon="arrow-thin-right" size="xs" />
</small>
</Link>
)}
<Link to="https://ravendb.net/community" className="menu__link group">
<Icon icon="community" size="xs" className="me-2" /> Community
<Icon icon="newtab" size="xs" className="ms-auto" />
</Link>
{sectionNavItems.map((item) => (
<li key={item.label} className="menu__list-item">
<SectionNavLink
item={item}
isActive={item.pathType === pathType}
onClick={() => mobileSidebar.toggle()}
/>
</li>
))}
{pathType === PathType.Documentation && (
<li className="menu__list-item">
<Link
Expand Down
59 changes: 58 additions & 1 deletion src/typescript/pathUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { IconName } from "./iconName";

export const PathType = {
Cloud: "CLOUD",
Quill: "QUILL",
Expand All @@ -11,7 +13,12 @@ export type PathTypeValue = (typeof PathType)[keyof typeof PathType];

// Versionless content areas, in match order. The URL segment doubles as the landing page path.
// Anything that matches none of these is versioned documentation.
const SECTIONS: readonly { segment: string; type: PathTypeValue }[] = [
interface Section {
segment: string;
type: PathTypeValue;
}

const SECTIONS: readonly Section[] = [
{ segment: "cloud", type: PathType.Cloud },
{ segment: "quill", type: PathType.Quill },
{ segment: "guides", type: PathType.Guides },
Expand All @@ -28,3 +35,53 @@ export function getLandingPagePath(pathType: PathTypeValue, versionLabel: string
const section = SECTIONS.find((candidate) => candidate.type === pathType);
return section ? `/${section.segment}` : `/${versionLabel}`;
}

export interface SectionNavItem {
label: string;
icon: IconName;
to: string;
pathType: PathTypeValue | null;
external?: boolean;
}

interface NavSection {
type: PathTypeValue;
label: string;
icon: IconName;
}

const NAV_SECTIONS: readonly NavSection[] = [
{ type: PathType.Documentation, label: "RavenDB Docs", icon: "database" },
{ type: PathType.Cloud, label: "RavenDB Cloud Docs", icon: "cloud" },
{ type: PathType.Quill, label: "Quill Docs", icon: "quill" },
{ type: PathType.Guides, label: "Guides", icon: "guides" },
{ type: PathType.Samples, label: "Samples", icon: "create-sample-data" },
];

const COMMUNITY: SectionNavItem = {
label: "Community",
icon: "community",
to: "https://ravendb.net/community",
pathType: null,
external: true,
};

export function getSectionNavItems(pathType: PathTypeValue, versionLabel: string): SectionNavItem[] {
// The section you are in keeps its place on the list, named for what the entry does rather
// than repeating the product name already shown in the header. The sidebars mark it active.
const start: SectionNavItem = {
label: "Start",
icon: "home",
to: getLandingPagePath(pathType, versionLabel),
pathType,
};

const others = NAV_SECTIONS.filter((section) => section.type !== pathType).map((section) => ({
label: section.label,
icon: section.icon,
to: getLandingPagePath(section.type, versionLabel),
pathType: section.type,
}));

return [start, ...others, COMMUNITY];
}
Loading