Skip to content

Commit 2e28a03

Browse files
committed
fixup! fix(web): shorten method labels in sidebar
1 parent 34995e9 commit 2e28a03

2 files changed

Lines changed: 96 additions & 18 deletions

File tree

src/generators/jsx-ast/utils/__tests__/buildBarProps.test.mjs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,50 @@ describe('extractHeadings', () => {
9191
assert.equal(result.value, 'crypto.createHash()');
9292
});
9393

94+
it('keeps full method labels when compact labels would collide', () => {
95+
const entries = [
96+
{
97+
heading: {
98+
depth: 3,
99+
data: {
100+
text: '`url.format(urlObject)`',
101+
name: 'format',
102+
slug: 'url-format-urlobject',
103+
type: 'method',
104+
},
105+
},
106+
},
107+
{
108+
heading: {
109+
depth: 3,
110+
data: {
111+
text: '`url.format(urlString)`',
112+
name: 'format',
113+
slug: 'url-format-urlstring',
114+
type: 'method',
115+
},
116+
},
117+
},
118+
{
119+
heading: {
120+
depth: 3,
121+
data: {
122+
text: '`url.parse(urlString)`',
123+
name: 'parse',
124+
slug: 'url-parse-urlstring',
125+
type: 'method',
126+
},
127+
},
128+
},
129+
];
130+
131+
const result = extractHeadings(entries);
132+
133+
assert.equal(result[0].value, 'url.format(urlObject)');
134+
assert.equal(result[1].value, 'url.format(urlString)');
135+
assert.equal(result[2].value, 'url.parse()');
136+
});
137+
94138
it('filters out entries with empty heading text', () => {
95139
const entries = [
96140
{

src/generators/jsx-ast/utils/buildBarProps.mjs

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ import { TOC_MAX_HEADING_DEPTH } from '../constants.mjs';
66

77
const SHORT_SIGNATURE_TYPES = new Set(['classMethod', 'ctor', 'method']);
88

9+
/**
10+
* Formats a full heading label for the table of contents.
11+
* @param {import('../../metadata/types').HeadingData} data
12+
*/
13+
const formatHeading = data =>
14+
data.text
15+
// Remove any containing code blocks
16+
.replace(/`/g, '')
17+
// Remove any prefixes (i.e. 'Class:')
18+
.replace(/^[^:]+:/, '')
19+
// Trim the remaining whitespace
20+
.trim();
21+
922
/**
1023
* Shortens method-like headings so the table of contents remains scannable.
1124
* @param {import('../../metadata/types').HeadingData} data
@@ -48,25 +61,11 @@ const shouldIncludeEntryInToC = ({ heading }) =>
4861
/**
4962
* Extracts and formats heading information from an API documentation entry.
5063
* @param {import('../../metadata/types').MetadataEntry} entry
64+
* @param {string} heading
5165
*/
52-
const extractHeading = entry => {
66+
const extractHeading = (entry, heading) => {
5367
const data = entry.heading.data;
5468

55-
const cliFlagOrEnv = [...data.text.matchAll(/`(-[\w-]+|[A-Z0-9_]+=)/g)];
56-
57-
const heading =
58-
cliFlagOrEnv.length > 0
59-
? cliFlagOrEnv.at(-1)[1]
60-
: SHORT_SIGNATURE_TYPES.has(data.type)
61-
? formatCodeHeading(data)
62-
: data.text
63-
// Remove any containing code blocks
64-
.replace(/`/g, '')
65-
// Remove any prefixes (i.e. 'Class:')
66-
.replace(/^[^:]+:/, '')
67-
// Trim the remaining whitespace
68-
.trim();
69-
7069
return {
7170
depth: entry.heading.depth,
7271
value: heading,
@@ -76,10 +75,45 @@ const extractHeading = entry => {
7675
};
7776
};
7877

78+
/**
79+
* Extracts both the full heading and the optional compact heading candidate.
80+
* @param {import('../../metadata/types').MetadataEntry} entry
81+
*/
82+
const prepareHeading = entry => {
83+
const data = entry.heading.data;
84+
const cliFlagOrEnv = [...data.text.matchAll(/`(-[\w-]+|[A-Z0-9_]+=)/g)];
85+
86+
if (cliFlagOrEnv.length > 0) {
87+
return { entry, heading: cliFlagOrEnv.at(-1)[1], compactHeading: null };
88+
}
89+
90+
return {
91+
entry,
92+
heading: formatHeading(data),
93+
compactHeading: SHORT_SIGNATURE_TYPES.has(data.type)
94+
? formatCodeHeading(data)
95+
: null,
96+
};
97+
};
98+
7999
/**
80100
* Build the list of heading metadata for sidebar navigation.
81101
*
82102
* @param {Array<import('../../metadata/types').MetadataEntry>} entries - All API metadata entries
83103
*/
84-
export const extractHeadings = entries =>
85-
entries.filter(shouldIncludeEntryInToC).map(extractHeading);
104+
export const extractHeadings = entries => {
105+
const headings = entries.filter(shouldIncludeEntryInToC).map(prepareHeading);
106+
const compactHeadingCounts = Map.groupBy(
107+
headings.filter(({ compactHeading }) => compactHeading),
108+
({ compactHeading }) => compactHeading
109+
);
110+
111+
return headings.map(({ entry, heading, compactHeading }) =>
112+
extractHeading(
113+
entry,
114+
compactHeading && compactHeadingCounts.get(compactHeading).length === 1
115+
? compactHeading
116+
: heading
117+
)
118+
);
119+
};

0 commit comments

Comments
 (0)