diff --git a/src/generators/web/ui/components/SideBar/index.jsx b/src/generators/web/ui/components/SideBar/index.jsx
index 31461108..d64fa13c 100644
--- a/src/generators/web/ui/components/SideBar/index.jsx
+++ b/src/generators/web/ui/components/SideBar/index.jsx
@@ -2,7 +2,7 @@ import Select from '@node-core/ui-components/Common/Select';
import SideBar from '@node-core/ui-components/Containers/Sidebar';
import styles from './index.module.css';
-import { STATIC_DATA } from '../../constants.mjs';
+import { STATIC_DATA, SIDEBAR_GROUPS } from '../../constants.mjs';
/**
* @typedef {Object} SideBarProps
@@ -18,6 +18,41 @@ import { STATIC_DATA } from '../../constants.mjs';
*/
const redirect = url => (window.location.href = url);
+/**
+ * Builds grouped sidebar navigation from flat docPages list.
+ * Pages not matching any group are placed under "Other".
+ * @param {Array<[string, string]>} docPages - [Title, URL] pairs
+ * @returns {Array<{ groupName: string, items: Array<{ label: string, link: string }> }>}
+ */
+const buildSideBarGroups = docPages => {
+ const linkMap = new Map(docPages.map(([label, link]) => [link, label]));
+ const assigned = new Set();
+
+ const groups = SIDEBAR_GROUPS.map(({ groupName, items }) => ({
+ groupName,
+ items: items
+ .filter(link => {
+ if (linkMap.has(link)) {
+ assigned.add(link);
+ return true;
+ }
+
+ return false;
+ })
+ .map(link => ({ label: linkMap.get(link), link })),
+ })).filter(group => group.items.length > 0);
+
+ const otherItems = docPages
+ .filter(([, link]) => !assigned.has(link))
+ .map(([label, link]) => ({ label, link }));
+
+ if (otherItems.length > 0) {
+ groups.push({ groupName: 'Other', items: otherItems });
+ }
+
+ return groups;
+};
+
/**
* Sidebar component for MDX documentation with version selection and page navigation
* @param {SideBarProps} props - Component props
@@ -25,25 +60,17 @@ const redirect = url => (window.location.href = url);
export default ({ versions, pathname, currentVersion, docPages }) => (
({ label, link })),
- },
- ]}
+ groups={buildSideBarGroups(docPages)}
onSelect={redirect}
as={props => }
title="Navigation"
>
-
-
-
+
);
diff --git a/src/generators/web/ui/constants.mjs b/src/generators/web/ui/constants.mjs
index 2d1b5802..be4ded1a 100644
--- a/src/generators/web/ui/constants.mjs
+++ b/src/generators/web/ui/constants.mjs
@@ -1,2 +1,120 @@
// eslint-disable-next-line no-undef
export const STATIC_DATA = __STATIC_DATA__;
+
+/**
+ * Defines the sidebar navigation groups and their associated page URLs.
+ * Pages not listed here will be placed under "Other".
+ * @type {Array<{ groupName: string, items: Array }>}
+ */
+export const SIDEBAR_GROUPS = [
+ {
+ groupName: 'Getting Started',
+ items: [
+ 'documentation.html',
+ 'synopsis.html',
+ 'cli.html',
+ 'environment_variables.html',
+ 'globals.html',
+ ],
+ },
+ {
+ groupName: 'Module System',
+ items: [
+ 'modules.html',
+ 'esm.html',
+ 'module.html',
+ 'packages.html',
+ 'typescript.html',
+ ],
+ },
+ {
+ groupName: 'Networking & Protocols',
+ items: [
+ 'http.html',
+ 'http2.html',
+ 'https.html',
+ 'net.html',
+ 'dns.html',
+ 'dgram.html',
+ ],
+ },
+ {
+ groupName: 'File System & I/O',
+ items: [
+ 'fs.html',
+ 'path.html',
+ 'buffer.html',
+ 'stream.html',
+ 'string_decoder.html',
+ 'zlib.html',
+ 'readline.html',
+ 'tty.html',
+ ],
+ },
+ {
+ groupName: 'Asynchronous Programming',
+ items: [
+ 'async_context.html',
+ 'async_hooks.html',
+ 'events.html',
+ 'timers.html',
+ 'webstreams.html',
+ ],
+ },
+ {
+ groupName: 'Process & Concurrency',
+ items: [
+ 'process.html',
+ 'child_process.html',
+ 'cluster.html',
+ 'worker_threads.html',
+ 'os.html',
+ ],
+ },
+ {
+ groupName: 'Security & Cryptography',
+ items: ['crypto.html', 'webcrypto.html', 'permissions.html', 'tls.html'],
+ },
+ {
+ groupName: 'Data & URL Utilities',
+ items: ['url.html', 'querystring.html', 'punycode.html', 'util.html'],
+ },
+ {
+ groupName: 'Debugging & Diagnostics',
+ items: [
+ 'debugger.html',
+ 'inspector.html',
+ 'console.html',
+ 'report.html',
+ 'tracing.html',
+ 'diagnostics_channel.html',
+ 'errors.html',
+ ],
+ },
+ {
+ groupName: 'Testing & Assertion',
+ items: ['test.html', 'assert.html', 'repl.html'],
+ },
+ {
+ groupName: 'Performance & Observability',
+ items: ['perf_hooks.html', 'v8.html'],
+ },
+ {
+ groupName: 'Runtime & Advanced APIs',
+ items: [
+ 'vm.html',
+ 'wasi.html',
+ 'sqlite.html',
+ 'single-executable-applications.html',
+ 'intl.html',
+ ],
+ },
+ {
+ groupName: 'Native & Low-level Extensions',
+ items: ['addons.html', 'n-api.html', 'embedding.html'],
+ },
+ {
+ groupName: 'Legacy & Deprecated',
+ items: ['deprecations.html', 'domain.html'],
+ },
+];
diff --git a/src/generators/web/ui/index.css b/src/generators/web/ui/index.css
index 3b0deb3e..f2fc3aea 100644
--- a/src/generators/web/ui/index.css
+++ b/src/generators/web/ui/index.css
@@ -118,3 +118,8 @@ main {
}
}
}
+
+/* Override the min-width of the select component used for version selection in the sidebar */
+[class*="select"] button[role="combobox"] {
+ min-width: initial;
+}