Skip to content

Commit 26a251e

Browse files
authored
feat: Expand long inline types (#82)
1 parent f59e2af commit 26a251e

File tree

7 files changed

+229
-25
lines changed

7 files changed

+229
-25
lines changed

fixtures/components/complex-types/button-group/interfaces.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
export interface ButtonGroupProps {
5+
/**
6+
* Main action for the group
7+
*/
8+
mainAction?: {
9+
alwaysFalse: false;
10+
alwaysOne: 1;
11+
alwaysSomething: 'something';
12+
};
13+
514
/**
615
* This is variant
716
*/

fixtures/components/slots/container/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,20 @@ export interface ContainerProps {
1313
* @displayname content
1414
*/
1515
children?: React.ReactNode;
16+
17+
/**
18+
* Media content
19+
*/
20+
media?: {
21+
content: React.ReactNode;
22+
};
1623
}
1724

18-
export default function Container({ header, children }: ContainerProps) {
25+
export default function Container({ header, children, media }: ContainerProps) {
1926
return (
2027
<div>
2128
<header>{header}</header>
29+
{media?.content}
2230
{children}
2331
</div>
2432
);

src/components/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export interface ObjectDefinitionProperty {
6363
name: string;
6464
optional: boolean;
6565
type: string;
66+
inlineType?: TypeDefinition;
6667
}
6768

6869
export interface FunctionDefinition {

src/components/object-definition.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ export function getObjectDefinition(
2222
const realTypeName = stringifyType(realType, checker);
2323
if (
2424
realType.flags & ts.TypeFlags.String ||
25-
realType.flags & ts.TypeFlags.StringLiteral ||
25+
realType.flags & ts.TypeFlags.Literal ||
2626
realType.flags & ts.TypeFlags.Boolean ||
2727
realType.flags & ts.TypeFlags.Number ||
2828
isArrayType(realType) ||
29-
realTypeName === 'HTMLElement'
29+
realTypeName === 'HTMLElement' ||
30+
type === 'React.ReactNode'
3031
) {
3132
// do not expand built-in Javascript methods or primitive values
3233
return { type };
@@ -38,24 +39,25 @@ export function getObjectDefinition(
3839
const properties = realType
3940
.getProperties()
4041
.map(prop => {
41-
const propType = checker.getTypeAtLocation(extractDeclaration(prop));
42+
const propNode = extractDeclaration(prop) as ts.PropertyDeclaration;
43+
const propType = checker.getTypeAtLocation(propNode);
44+
const typeString = stringifyType(propType, checker);
45+
4246
return {
4347
name: prop.getName(),
44-
type: stringifyType(propType, checker),
4548
optional: isOptional(propType),
49+
...getObjectDefinition(typeString, propType, propNode.type, checker),
4650
};
4751
})
4852
.sort((a, b) => a.name.localeCompare(b.name));
49-
if (properties.every(prop => prop.type.length < 200)) {
50-
return {
51-
type: type,
52-
inlineType: {
53-
name: realTypeName,
54-
type: 'object',
55-
properties: properties,
56-
},
57-
};
58-
}
53+
return {
54+
type: type,
55+
inlineType: {
56+
name: realTypeName.length < 100 ? realTypeName : 'object',
57+
type: 'object',
58+
properties: properties,
59+
},
60+
};
5961
}
6062
if (realType.getCallSignatures().length > 0) {
6163
if (realType.getCallSignatures().length > 1) {
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`should print long inline types 1`] = `
4+
[
5+
{
6+
"analyticsTag": undefined,
7+
"defaultValue": undefined,
8+
"deprecatedTag": undefined,
9+
"description": undefined,
10+
"i18nTag": undefined,
11+
"inlineType": {
12+
"name": "ButtonProps.Style",
13+
"properties": [
14+
{
15+
"inlineType": {
16+
"name": "object",
17+
"properties": [
18+
{
19+
"inlineType": {
20+
"name": "object",
21+
"properties": [
22+
{
23+
"name": "active",
24+
"optional": true,
25+
"type": "string",
26+
},
27+
{
28+
"name": "default",
29+
"optional": true,
30+
"type": "string",
31+
},
32+
{
33+
"name": "disabled",
34+
"optional": true,
35+
"type": "string",
36+
},
37+
{
38+
"name": "hover",
39+
"optional": true,
40+
"type": "string",
41+
},
42+
],
43+
"type": "object",
44+
},
45+
"name": "background",
46+
"optional": true,
47+
"type": "{ active?: string | undefined; default?: string | undefined; disabled?: string | undefined; hover?: string | undefined; }",
48+
},
49+
{
50+
"inlineType": {
51+
"name": "object",
52+
"properties": [
53+
{
54+
"name": "active",
55+
"optional": true,
56+
"type": "string",
57+
},
58+
{
59+
"name": "default",
60+
"optional": true,
61+
"type": "string",
62+
},
63+
{
64+
"name": "disabled",
65+
"optional": true,
66+
"type": "string",
67+
},
68+
{
69+
"name": "hover",
70+
"optional": true,
71+
"type": "string",
72+
},
73+
],
74+
"type": "object",
75+
},
76+
"name": "borderColor",
77+
"optional": true,
78+
"type": "{ active?: string | undefined; default?: string | undefined; disabled?: string | undefined; hover?: string | undefined; }",
79+
},
80+
{
81+
"inlineType": {
82+
"name": "object",
83+
"properties": [
84+
{
85+
"name": "active",
86+
"optional": true,
87+
"type": "string",
88+
},
89+
{
90+
"name": "default",
91+
"optional": true,
92+
"type": "string",
93+
},
94+
{
95+
"name": "disabled",
96+
"optional": true,
97+
"type": "string",
98+
},
99+
{
100+
"name": "hover",
101+
"optional": true,
102+
"type": "string",
103+
},
104+
],
105+
"type": "object",
106+
},
107+
"name": "color",
108+
"optional": true,
109+
"type": "{ active?: string | undefined; default?: string | undefined; disabled?: string | undefined; hover?: string | undefined; }",
110+
},
111+
],
112+
"type": "object",
113+
},
114+
"name": "root",
115+
"optional": true,
116+
"type": "{ background?: { active?: string | undefined; default?: string | undefined; disabled?: string | undefined; hover?: string | undefined; } | undefined; color?: { active?: string | undefined; default?: string | undefined; disabled?: string | undefined; hover?: string | undefined; } | undefined; borderColor?: { ...; } |...",
117+
},
118+
],
119+
"type": "object",
120+
},
121+
"name": "style",
122+
"optional": false,
123+
"systemTags": undefined,
124+
"type": "ButtonProps.Style",
125+
"visualRefreshTag": undefined,
126+
},
127+
]
128+
`;

test/components/complex-types.test.ts

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ test('should have correct property types', () => {
6060
name: 'allItemsSelectionLabel',
6161
optional: true,
6262
type: '((data: TableProps.SelectionState<T>) => string)',
63+
inlineType: {
64+
name: '(data: TableProps.SelectionState<T>) => string',
65+
parameters: [
66+
{
67+
name: 'data',
68+
type: 'TableProps.SelectionState<T>',
69+
},
70+
],
71+
returnType: 'string',
72+
type: 'function',
73+
},
6374
},
6475
],
6576
},
@@ -149,7 +160,13 @@ test('should properly display string union types', () => {
149160
{
150161
name: 'type',
151162
optional: true,
152-
type: '"link" | "link-group" | "expandable-link-group"',
163+
type: 'string',
164+
inlineType: {
165+
name: '"link" | "link-group" | "expandable-link-group"',
166+
type: 'union',
167+
valueDescriptions: undefined,
168+
values: ['link', 'link-group', 'expandable-link-group'],
169+
},
153170
},
154171
],
155172
});
@@ -186,6 +203,33 @@ test('should parse string literal type as single-value union', () => {
186203
type: 'ReadonlyArray<ButtonGroupProps.Item>',
187204
optional: false,
188205
},
206+
{
207+
name: 'mainAction',
208+
description: 'Main action for the group',
209+
type: '{ alwaysFalse: false; alwaysOne: 1; alwaysSomething: "something"; }',
210+
optional: true,
211+
inlineType: {
212+
name: '{ alwaysFalse: false; alwaysOne: 1; alwaysSomething: "something"; }',
213+
type: 'object',
214+
properties: [
215+
{
216+
name: 'alwaysFalse',
217+
optional: false,
218+
type: 'false',
219+
},
220+
{
221+
name: 'alwaysOne',
222+
optional: false,
223+
type: '1',
224+
},
225+
{
226+
name: 'alwaysSomething',
227+
optional: false,
228+
type: '"something"',
229+
},
230+
],
231+
},
232+
},
189233
{
190234
name: 'variant',
191235
description: 'This is variant',
@@ -195,12 +239,6 @@ test('should parse string literal type as single-value union', () => {
195239
]);
196240
});
197241

198-
test('should trim long inline types', () => {
199-
expect(button.properties).toEqual([
200-
{
201-
name: 'style',
202-
type: 'ButtonProps.Style',
203-
optional: false,
204-
},
205-
]);
242+
test('should print long inline types', () => {
243+
expect(button.properties).toMatchSnapshot();
206244
});

test/components/slots.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,25 @@ beforeAll(() => {
1313
});
1414

1515
test('should have correct region definitions', () => {
16-
expect(component.properties).toEqual([]);
16+
expect(component.properties).toEqual([
17+
{
18+
name: 'media',
19+
description: 'Media content',
20+
optional: true,
21+
type: '{ content: React.ReactNode; }',
22+
inlineType: {
23+
name: '{ content: React.ReactNode; }',
24+
properties: [
25+
{
26+
name: 'content',
27+
optional: true,
28+
type: 'React.ReactNode',
29+
},
30+
],
31+
type: 'object',
32+
},
33+
},
34+
]);
1735
expect(component.regions).toEqual([
1836
{
1937
name: 'children',

0 commit comments

Comments
 (0)