Skip to content
Merged
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
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@std/fs": "jsr:@std/fs@^1.0.19",
"@std/path": "jsr:@std/path@^1.1.2",
"@types/yauzl": "npm:@types/yauzl@^2.10.3",
"astro": "npm:astro@^5.13.0",
"astro": "npm:astro@5.13.8",
"yauzl": "npm:yauzl@^3.2.0"
},
"nodeModulesDir": "auto"
Expand Down
4 changes: 2 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,28 @@
}
}

.project-switcher-content ul {
display: grid;
gap: 0.25rem;
list-style: none;
padding: 0;
.project-switcher-sections a {
padding: 0.25rem;
width: 100%;
}

.project-switcher-sections {
display: flex;
flex-direction: column;
gap: 0.25rem;
}

.project-switcher-section-title {
font-size: var(--sl-text-h5);
font-weight: 600;
color: var(--sl-color-text-secondary);
padding: 0 0.25rem;
}

.project-switcher-section-title:not(:first-child) {
margin-top: 0.75rem;
}

@media (width >= 48rem) {
.project-switcher {
width: auto;
Expand All @@ -102,9 +116,26 @@
width: max-content;
justify-content: center;
}
.project-switcher-content ul {
.project-switcher-sections a {
padding: 0.75rem;
width: 300px;
}
.project-switcher-sections {
display: grid;
grid-template:
"title-libraries title-tools"
/ 1fr 1fr;
gap: 0.75rem;
}
.project-switcher-section-title {
margin-top: 0 !important;
}
#project-switcher-section-title-libraries {
grid-area: title-libraries;
}
#project-switcher-section-title-tools {
grid-area: title-tools;
}
}

/* Animate open/close when toggling the menu */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,64 @@ import pluginConfig from "virtual:starlight-multi-sidebar/config";
import "./ProjectSwitcher.css";

type Header = MultiSidebarConfig["sidebars"][number]["header"];
type HeaderItem = {
basePath: MultiSidebarConfig["sidebars"][number]["basePath"];
header: Header;
};
type HeadersByCategory = Record<
Header["category"],
{
items: Array<HeaderItem>;
}
>;

const headersByCategory = pluginConfig.sidebars.reduce<HeadersByCategory>(
(acc, sidebar) => {
acc[sidebar.header.category].items.push({
basePath: sidebar.basePath,
header: sidebar.header,
});
return acc;
},
{ library: { items: [] }, tool: { items: [] } },
);

type Props = {
type NavigationLinkProps = React.ComponentProps<typeof NavigationMenu.Link> & {
projectPath: string;
currentHeader?: Header | undefined;
headerItem: HeaderItem;
};

const NavigationLink: React.FC<NavigationLinkProps> = ({
projectPath,
headerItem,
...props
}) => {
const isActive = projectPath.startsWith(headerItem.basePath);

return (
<NavigationMenu.Link className="project-switcher-link" asChild {...props}>
<a
href={headerItem.basePath}
className={isActive ? "active" : undefined}
role="menuitem"
>
<div className="project-switcher-link-title">
{headerItem.header.title}
</div>
<div className="project-switcher-link-description">
{headerItem.header.description}
</div>
</a>
</NavigationMenu.Link>
);
};

const headers = pluginConfig.sidebars.map((sidebar) => ({
basePath: sidebar.basePath,
header: sidebar.header,
}));
type ProjectSwitcherProps = {
projectPath: string;
currentHeader?: Header | undefined;
};

export const ProjectSwitcherReact: React.FC<Props> = ({
export const ProjectSwitcherReact: React.FC<ProjectSwitcherProps> = ({
projectPath,
currentHeader,
}) => {
Expand Down Expand Up @@ -54,32 +100,44 @@ export const ProjectSwitcherReact: React.FC<Props> = ({
data-slot="navigation-menu-content"
className="project-switcher-content"
>
<ul>
{headers.map((h) => {
const isActive = projectPath?.startsWith(h.basePath);
return (
<li key={h.basePath}>
<NavigationMenu.Link
className="project-switcher-link"
asChild
>
<a
href={h.basePath}
className={isActive ? "active" : undefined}
role="menuitem"
>
<div className="project-switcher-link-title">
{h.header.title}
</div>
<div className="project-switcher-link-description">
{h.header.description}
</div>
</a>
</NavigationMenu.Link>
</li>
);
})}
</ul>
<div className="project-switcher-sections" role="menu">
{headersByCategory.library.items.length > 0 && (
<>
<div
className="project-switcher-section-title"
id="project-switcher-section-title-libraries"
>
Libraries
</div>
{headersByCategory.library.items.map((h, i) => (
<NavigationLink
key={h.basePath}
projectPath={projectPath}
headerItem={h}
style={{ gridColumnStart: "1", gridRowStart: i + 2 }}
/>
))}
</>
)}
{headersByCategory.tool.items.length > 0 && (
<>
<div
className="project-switcher-section-title"
id="project-switcher-section-title-tools"
>
Tools
</div>
{headersByCategory.tool.items.map((h, i) => (
<NavigationLink
key={h.basePath}
projectPath={projectPath}
headerItem={h}
style={{ gridColumnStart: "2", gridRowStart: i + 2 }}
/>
))}
</>
)}
</div>
</NavigationMenu.Content>
</NavigationMenu.Item>
<NavigationMenu.Indicator
Expand Down
1 change: 1 addition & 0 deletions docs/plugins/multi-sidebar/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const versionSchema = z.object({
const headerSchema = z.object({
title: z.string(),
description: z.string(),
category: z.enum(["library", "tool"]),
githubRepo: z.string(),
});

Expand Down
1 change: 1 addition & 0 deletions docs/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function getSidebarsFromProjects(
header: {
title: project.title,
description: project.description,
category: project.category,
githubRepo: project.repository,
},
});
Expand Down
4 changes: 4 additions & 0 deletions projects-schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ export interface Project {
* The public/... subdirectory where to save the static assets pulled from the repository
*/
subdirectory: string;
/**
* The most appropriate category for the project
*/
category: "library" | "tool";
}
12 changes: 11 additions & 1 deletion projects-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,19 @@
"type": "string",
"description": "The public/... subdirectory where to save the static assets pulled from the repository",
"examples": ["core"]
},
"category": {
"enum": ["library", "tool"],
"description": "The most appropriate category for the project"
}
},
"required": ["title", "description", "repository", "subdirectory"],
"required": [
"title",
"description",
"repository",
"subdirectory",
"category"
],
"title": "Project"
}
}
Expand Down
6 changes: 4 additions & 2 deletions projects.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
"projects": [
{
"title": "Core",
"description": "Base library for Internet Computer apps.",
"description": "Base library for ICP apps",
"category": "library",
"repository": "dfinity/icp-js-core",
"branch": "icp-pages",
"subdirectory": "core"
},
{
"title": "Pic JS",
"description": "An ICP canister testing library for TypeScript and JavaScript.",
"description": "A canister testing framework",
"category": "tool",
"repository": "dfinity/pic-js",
"branch": "icp-pages",
"subdirectory": "pic-js"
Expand Down