Skip to content

Commit a002cc3

Browse files
committed
better sidebar gen
1 parent e5085dd commit a002cc3

File tree

6 files changed

+66
-75
lines changed

6 files changed

+66
-75
lines changed

src/generators/jsx/constants.mjs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
// Maps the the stability index (0-3) to the level used by @node-core/ui-components
1+
// Maps Node.js API stability indices (0-3) to UI component stability levels.
22
export const STABILITY_LEVELS = [
33
'danger', // (0) Deprecated
44
'warning', // (1) Experimental
55
'success', // (2) Stable
66
'info', // (3) Legacy
77
];
88

9-
// Maps HTML tags to corresponding component names in @node-core/ui-components
9+
// Maps HTML tags to corresponding component names in @node-core/ui-components.
1010
export const TAG_TRANSFORMS = {
1111
pre: 'CodeBox',
1212
blockquote: 'Blockquote',
1313
};
1414

15-
// Maps types to icon symbols
15+
// Maps API heading types to their CircularIcon props.
1616
export const ICON_SYMBOL_MAP = {
1717
event: { symbol: 'E', color: 'red' },
1818
method: { symbol: 'M', color: 'red' },
@@ -23,6 +23,7 @@ export const ICON_SYMBOL_MAP = {
2323
ctor: { symbol: 'C', color: 'red' },
2424
};
2525

26+
// Maps API lifecycle change type identifiers to their human-readable labels.
2627
export const CHANGE_TYPES = {
2728
added_in: 'Added in',
2829
deprecated_in: 'Deprecated in',

src/generators/jsx/index.mjs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import {
2-
coerceSemVer,
32
getCompatibleVersions,
43
groupNodesByModule,
54
} from '../../utils/generators.mjs';
65
import buildContent from './utils/buildContent.mjs';
76
import { getRemarkRecma } from '../../utils/remark.mjs';
8-
import { major } from 'semver';
7+
import { buildSideBarDocPages } from './utils/buildBarProps.mjs';
98

109
/**
1110
* This generator generates a JSX AST from an input MDAST
@@ -37,24 +36,19 @@ export default {
3736
.sort((a, b) => a.heading.data.name.localeCompare(b.heading.data.name));
3837

3938
// Generate table of contents
40-
const docPages = headNodes.map(node => [
41-
node.heading.data.name,
42-
`${node.api}.html`,
43-
]);
39+
const docPages = buildSideBarDocPages(groupedModules, headNodes);
4440

4541
// Process each head node and build content
4642
const results = await Promise.all(
4743
headNodes.map(entry => {
48-
const coercedMajor = major(coerceSemVer(entry.introduced_in));
49-
const otherVersions = getCompatibleVersions(
44+
const versions = getCompatibleVersions(
5045
entry.introduced_in,
51-
releases
52-
).filter(({ version }) => version.major != coercedMajor);
46+
releases,
47+
true
48+
);
5349

5450
const sideBarProps = {
55-
otherVersions: otherVersions.map(
56-
({ version }) => `v${version.major}.x`
57-
),
51+
versions: versions.map(({ version }) => `v${version.version}`),
5852
currentVersion: `v${version.version}`,
5953
currentPage: `${entry.api}.html`,
6054
docPages,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import readingTime from 'reading-time';
2+
import { DOC_API_BLOB_EDIT_BASE_URL } from '../../../constants.mjs';
3+
import { visit } from 'unist-util-visit';
4+
5+
/**
6+
* Builds sidebar navigation for API documentation pages
7+
*
8+
* @param {Map<string, Array<ApiDocMetadataEntry>>} groupedModules - Modules grouped by API
9+
* @param {Array<ApiDocMetadataEntry>} headNodes - Main entry nodes for each API
10+
*/
11+
export const buildSideBarDocPages = (groupedModules, headNodes) =>
12+
headNodes.map(node => {
13+
const moduleEntries = groupedModules.get(node.api);
14+
15+
return {
16+
title: node.heading.data.name,
17+
doc: `${node.api}.html`,
18+
headings: moduleEntries
19+
.filter(entry => entry.heading?.data?.name && entry.heading.depth === 2)
20+
.map(entry => [entry.heading.data.name, `#${entry.heading.data.slug}`]),
21+
};
22+
});
23+
24+
/**
25+
* Builds metadata for the sidebar and meta bar
26+
*
27+
* @param {ApiDocMetadataEntry} head - Main API metadata entry
28+
* @param {Array<ApiDocMetadataEntry>} entries - All API metadata entries
29+
*/
30+
export function buildMetaBarProps(head, entries) {
31+
// Extract text content for reading time calculation
32+
let textContent = '';
33+
entries.forEach(entry => {
34+
visit(entry.content, ['text', 'code'], node => {
35+
textContent += node.value || '';
36+
});
37+
});
38+
39+
return {
40+
headings: entries
41+
.filter(entry => entry.heading?.data?.name)
42+
.map(entry => ({
43+
depth: entry.heading.depth,
44+
value: entry.heading.data.name,
45+
})),
46+
addedIn: head.introduced_in || head.added_in || '',
47+
readingTime: readingTime(textContent).text,
48+
viewAs: [['JSON', `${head.api}.json`]],
49+
editThisPage: `${DOC_API_BLOB_EDIT_BASE_URL}${head.api}.md`,
50+
};
51+
}

src/generators/jsx/utils/buildContent.mjs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@ import {
1111
STABILITY_LEVELS,
1212
CHANGE_TYPES,
1313
} from '../constants.mjs';
14-
import {
15-
DOC_API_BLOB_EDIT_BASE_URL,
16-
DOC_NODE_BLOB_BASE_URL,
17-
} from '../../../constants.mjs';
14+
import { DOC_NODE_BLOB_BASE_URL } from '../../../constants.mjs';
1815
import { enforceArray, sortChanges } from '../../../utils/generators.mjs';
19-
import readingTime from 'reading-time';
16+
import { buildMetaBarProps } from './buildBarProps.mjs';
2017

2118
/**
2219
* Transforms a stability node into an AlertBox JSX element
@@ -151,50 +148,6 @@ function processEntry(entry) {
151148
return content;
152149
}
153150

154-
/**
155-
* Collects text content from nodes for reading time calculation
156-
*
157-
* @param {Array<ApiDocMetadataEntry>} entries - The API metadata entries
158-
* @returns {string} Concatenated text content
159-
*/
160-
function collectTextContent(entries) {
161-
let text = '';
162-
entries.forEach(entry => {
163-
visit(entry.content, ['text', 'code'], node => {
164-
text += node.value || '';
165-
});
166-
});
167-
return text;
168-
}
169-
170-
/**
171-
* Builds the metadata for the sidebar and meta bar
172-
*
173-
* @param {ApiDocMetadataEntry} head - The main API metadata entry
174-
* @param {Array<ApiDocMetadataEntry>} entries - The API metadata entries
175-
* @returns {Object} Props for meta bar including headings and reading time
176-
*/
177-
function buildMetaBarProps(head, entries) {
178-
// Extract headings in one pass
179-
const headings = entries
180-
.filter(({ heading }) => heading?.data?.name)
181-
.map(({ heading }) => ({
182-
depth: heading.depth,
183-
value: heading.data.name,
184-
}));
185-
186-
// Calculate reading time
187-
const text = collectTextContent(entries);
188-
189-
return {
190-
headings,
191-
addedIn: head.introduced_in || head.added_in || '',
192-
readingTime: readingTime(text).text,
193-
viewAs: [['JSON', `${head.api}.json`]],
194-
editThisPage: `${DOC_API_BLOB_EDIT_BASE_URL}${head.api}.md`,
195-
};
196-
}
197-
198151
/**
199152
* Creates the overall content structure with processed entries
200153
*

src/generators/jsx/utils/transformer.mjs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
/**
2-
* Imports the visit utility from unist-util-visit for traversing syntax trees.
3-
*/
41
import { visit } from 'unist-util-visit';
52
import { TAG_TRANSFORMS } from '../constants.mjs';
63

74
/**
8-
* Transforms elements in a syntax tree by replacing tag names according to a mapping.
9-
* Traverses the tree and replaces any element's tagName if it exists as a key in the tagMap.
5+
* Transforms elements in a syntax tree by replacing tag names according to the mapping.
106
*
117
* @param {Object} tree - The abstract syntax tree to transform
128
* @returns {Object} The transformed tree (modified in place)
13-
* @throws {ReferenceError} Will throw if 'tagMap' is not defined in scope
149
*/
1510
export default () => tree => {
16-
// TODO(@avivkeller): Nodes like "Array<string>" return a "<string>" raw type,
17-
// which Recma does not understand, so we make them text.
18-
1911
visit(tree, 'raw', node => {
2012
node.type = 'text';
2113
});

src/utils/generators.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ export const coerceSemVer = version => {
5959
*
6060
* @param {string | import('semver').SemVer} introduced
6161
* @param {Array<Release>} releases
62+
* @param {Boolean} [includeNonMajor=false]
6263
* @returns {Array<Release>}
6364
*/
6465
export const getCompatibleVersions = (introduced, releases) => {
65-
if (!introduced) return releases;
6666
const coercedMajor = major(coerceSemVer(introduced));
6767
// All Node.js versions that support the current API; If there's no "introduced_at" field,
6868
// we simply show all versions, as we cannot pinpoint the exact version

0 commit comments

Comments
 (0)