Skip to content

Commit 8294404

Browse files
authored
fix(site): resolve aliased part descriptions in api docs (#518)
1 parent 4d62a1f commit 8294404

File tree

6 files changed

+49
-9
lines changed

6 files changed

+49
-9
lines changed

packages/react/src/ui/controls/controls-group.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface ControlsGroupProps extends UIComponentProps<'div', GroupState>
1212
children?: ReactNode | undefined;
1313
}
1414

15+
/** Layout group for related controls; sets `role="group"` when labeled. */
1516
export const ControlsGroup = forwardRef(function ControlsGroup(
1617
componentProps: ControlsGroupProps,
1718
forwardedRef: ForwardedRef<HTMLDivElement>

packages/react/src/ui/controls/controls-root.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface ControlsRootProps extends UIComponentProps<'div', ControlsCore.
1313
children?: ReactNode | undefined;
1414
}
1515

16+
/** Root container for player controls state and rendered control content. */
1617
export const ControlsRoot = forwardRef(function ControlsRoot(
1718
componentProps: ControlsRootProps,
1819
forwardedRef: ForwardedRef<HTMLDivElement>

site/scripts/api-docs-builder/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ function discoverParts(source: ComponentSource, program: ts.Program): PartSource
265265

266266
const part: PartSource = {
267267
name: partExport.name,
268+
localName: partExport.localName,
268269
kebab,
269270
isPrimary,
270271
htmlPath: hasSubPartElement ? subPartElementFile : isPrimary ? source.htmlPath : undefined,
@@ -310,7 +311,10 @@ function buildMultiPartApiReference(
310311

311312
for (const part of parts) {
312313
// Extract JSDoc description from React component file
313-
const description = part.reactPath ? extractPartDescription(part.reactPath, program, part.name) : undefined;
314+
const description = part.reactPath
315+
? (extractPartDescription(part.reactPath, program, part.localName) ??
316+
extractPartDescription(part.reactPath, program, part.name))
317+
: undefined;
314318

315319
if (part.isPrimary) {
316320
// Primary part: extract from shared core and data-attrs

site/scripts/api-docs-builder/src/parts-handler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import * as ts from 'typescript';
22
import * as tae from 'typescript-api-extractor';
33

44
export interface PartExport {
5-
/** PascalCase export name (e.g., "Value", "Group", "Separator"). */
5+
/** PascalCase exported part name (e.g., "Value", "Group", "Separator"). */
66
name: string;
7+
/** Local symbol name in the source module before aliasing. */
8+
localName: string;
79
/** Source path (e.g., "./time-value", "./time-group"). */
810
source: string;
911
}
@@ -39,8 +41,10 @@ export function extractParts(filePath: string, program: ts.Program): PartExport[
3941
// Skip type-only specifiers (e.g., `type GroupProps`)
4042
if (element.isTypeOnly) continue;
4143

44+
const localName = element.propertyName?.text ?? element.name.text;
4245
parts.push({
4346
name: element.name.text,
47+
localName,
4448
source,
4549
});
4650
}

site/scripts/api-docs-builder/src/tests/parts-handler.test.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ describe('extractParts', () => {
2424
const result = extractParts('test.ts', program);
2525

2626
expect(result).toEqual([
27-
{ name: 'Group', source: './time-group' },
28-
{ name: 'Separator', source: './time-separator' },
29-
{ name: 'Value', source: './time-value' },
27+
{ name: 'Group', localName: 'Group', source: './time-group' },
28+
{ name: 'Separator', localName: 'Separator', source: './time-separator' },
29+
{ name: 'Value', localName: 'Value', source: './time-value' },
3030
]);
3131
});
3232

@@ -38,7 +38,7 @@ describe('extractParts', () => {
3838
const program = createTestProgram(code);
3939
const result = extractParts('test.ts', program);
4040

41-
expect(result).toEqual([{ name: 'Group', source: './time-group' }]);
41+
expect(result).toEqual([{ name: 'Group', localName: 'Group', source: './time-group' }]);
4242
});
4343

4444
it('returns empty array for file with no exports', () => {
@@ -57,8 +57,8 @@ describe('extractParts', () => {
5757
const result = extractParts('test.ts', program);
5858

5959
expect(result).toEqual([
60-
{ name: 'Foo', source: './source' },
61-
{ name: 'Bar', source: './source' },
60+
{ name: 'Foo', localName: 'Foo', source: './source' },
61+
{ name: 'Bar', localName: 'Bar', source: './source' },
6262
]);
6363
});
6464

@@ -69,7 +69,17 @@ describe('extractParts', () => {
6969
const program = createTestProgram(code);
7070
const result = extractParts('test.ts', program);
7171

72-
expect(result).toEqual([{ name: 'Value', source: './time-value' }]);
72+
expect(result).toEqual([{ name: 'Value', localName: 'Value', source: './time-value' }]);
73+
});
74+
75+
it('captures local symbol name for aliased exports', () => {
76+
const code = `
77+
export { ControlsRoot as Root, type ControlsRootProps as RootProps } from './controls-root';
78+
`;
79+
const program = createTestProgram(code);
80+
const result = extractParts('test.ts', program);
81+
82+
expect(result).toEqual([{ name: 'Root', localName: 'ControlsRoot', source: './controls-root' }]);
7383
});
7484
});
7585

@@ -110,6 +120,24 @@ describe('extractPartDescription', () => {
110120
expect(result).toBe('Container for composed time displays.');
111121
});
112122

123+
it('extracts JSDoc description from a local (non-aliased) symbol name', () => {
124+
const program = createTestProgram('');
125+
mockParseFromProgram.mockReturnValue({
126+
exports: [
127+
{
128+
name: 'ControlsRoot',
129+
documentation: {
130+
description: 'Root container for player controls.',
131+
},
132+
},
133+
],
134+
});
135+
136+
const result = extractPartDescription('test.tsx', program, 'ControlsRoot');
137+
138+
expect(result).toBe('Root container for player controls.');
139+
});
140+
113141
it('returns undefined when export is not found', () => {
114142
const program = createTestProgram('');
115143
mockParseFromProgram.mockReturnValue({

site/scripts/api-docs-builder/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export { ComponentApiReferenceSchema, PartApiReferenceSchema } from '../../../sr
1818
export interface PartSource {
1919
/** PascalCase name (e.g., "Value", "Group", "Separator"). */
2020
name: string;
21+
/** Local symbol name in the source module (before any aliasing). */
22+
localName: string;
2123
/** Kebab-case segment (e.g., "value", "group", "separator"). */
2224
kebab: string;
2325
/** True if this part gets the shared core/data-attrs. */

0 commit comments

Comments
 (0)