Skip to content

Commit 5eab178

Browse files
authored
docs: create correct prop header to be displayed in TOC (#4018)
1 parent 3dc3fda commit 5eab178

File tree

6 files changed

+86
-44
lines changed

6 files changed

+86
-44
lines changed

docs/component-docs-plugin/generatePageMDX.js

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ const config = require('../docusaurus.config');
22

33
const { baseUrl, customFields } = config;
44

5+
function renderBadge(annotation) {
6+
const [annotType, ...annotLabel] = annotation.split(' ');
7+
8+
// eslint-disable-next-line prettier/prettier
9+
return `<span class="badge badge-${annotType.replace('@', '')} "><span class="badge-text">${annotLabel.join(' ')}</span></span>`;
10+
}
11+
512
function generateKnownIssues(componentName) {
613
const componentKnownIssues = customFields.knownIssues[componentName];
714

@@ -79,6 +86,54 @@ function generateScreenshots(componentName, screenshotData) {
7986
`;
8087
}
8188

89+
function generatePropsTable(data, link) {
90+
const ANNOTATION_OPTIONAL = '@optional';
91+
const ANNOTATION_INTERNAL = '@internal';
92+
93+
const props = Object.entries(data)
94+
.map(([prop, value]) => {
95+
if (!value.description) {
96+
value.description = '';
97+
}
98+
// Remove @optional annotations from descriptions.
99+
if (value.description.includes(ANNOTATION_OPTIONAL)) {
100+
value.description = value.description.replace(ANNOTATION_OPTIONAL, '');
101+
}
102+
// Hide props with @internal annotations.
103+
if (value.description.includes(ANNOTATION_INTERNAL)) {
104+
return;
105+
}
106+
107+
let leadingBadge = '';
108+
let descriptionByLines = value.description?.split('\n');
109+
110+
// Find leading badge and put it next after prop name.
111+
if (descriptionByLines?.[0].includes('@')) {
112+
leadingBadge = descriptionByLines[0];
113+
}
114+
115+
return `
116+
<div>
117+
118+
### ${prop} ${value.required ? '(required)' : ''} ${
119+
leadingBadge && renderBadge(leadingBadge)
120+
}
121+
122+
</div>
123+
124+
<PropTable componentLink="${link}" prop="${prop}" />
125+
126+
---
127+
`;
128+
})
129+
.join('');
130+
131+
return `
132+
## Props
133+
${props}
134+
`;
135+
}
136+
82137
function generatePageMDX(doc, link) {
83138
const summaryRegex = /([\s\S]*?)## Usage/;
84139

@@ -111,11 +166,9 @@ ${generateScreenshots(doc.title, screenshotData)}
111166
112167
${usage}
113168
114-
${generateMoreExamples(doc.title)}
115-
116-
## Props
169+
${generatePropsTable(doc.data.props, link)}
117170
118-
<PropTable link="${link}" />
171+
${generateMoreExamples(doc.title)}
119172
120173
${generateThemeColors(doc.title, themeColorsData)}
121174

docs/src/components/PropTable.tsx

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ const typeDefinitions = {
1717
'StyleProp<TextStyle>': 'https://reactnative.dev/docs/text-style-props',
1818
};
1919

20-
const ANNOTATION_OPTIONAL = '@optional';
21-
const ANNOTATION_INTERNAL = '@internal';
2220
const ANNOTATION_EXTENDS = '@extends';
2321

2422
const renderBadge = (annotation: string) => {
@@ -60,42 +58,31 @@ const renderExtendsLink = (description: string) => {
6058
));
6159
};
6260

63-
export default function PropTable({ link }: { link: string }) {
64-
const doc = useDoc(link);
61+
export default function PropTable({
62+
componentLink,
63+
prop,
64+
}: {
65+
componentLink: string;
66+
prop: string;
67+
}) {
68+
const doc = useDoc(componentLink);
6569

6670
if (!doc || !doc.data || !doc.data.props) {
6771
return null;
6872
}
6973

7074
const props = doc.data.props;
7175

72-
for (const prop in props) {
73-
if (!props[prop].description) {
74-
props[prop].description = '';
75-
}
76-
77-
// Remove @optional annotations from descriptions.
78-
if (props[prop].description.includes(ANNOTATION_OPTIONAL)) {
79-
props[prop].description = props[prop].description.replace(
80-
ANNOTATION_OPTIONAL,
81-
''
82-
);
83-
}
84-
// Hide props with @internal annotations.
85-
if (props[prop].description.includes(ANNOTATION_INTERNAL)) {
86-
delete props[prop];
87-
}
88-
}
89-
9076
return (
9177
<div>
9278
{Object.keys(props).map((key) => {
93-
let leadingBadge = '';
79+
if (key !== prop) {
80+
return null;
81+
}
9482
let descriptionByLines = props[key].description.split('\n');
9583

96-
// Find leading badge and put it next after prop name.
84+
// Slice leading badge - it's handled in `generatePageMDX`
9785
if (descriptionByLines[0].includes('@')) {
98-
leadingBadge = descriptionByLines[0];
9986
descriptionByLines = descriptionByLines.slice(1);
10087
}
10188
descriptionByLines = descriptionByLines.map((line: string) => {
@@ -116,16 +103,6 @@ export default function PropTable({ link }: { link: string }) {
116103

117104
return (
118105
<div key={key}>
119-
<h3>
120-
{key} {props[key].required ? '(required)' : ''}
121-
{leadingBadge && (
122-
<span
123-
dangerouslySetInnerHTML={{
124-
__html: renderBadge(leadingBadge),
125-
}}
126-
/>
127-
)}
128-
</h3>
129106
<p>
130107
Type:{' '}
131108
{tsTypeLink ? (

docs/src/css/custom.css

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ html[data-theme='light'] .gallery-dark {
187187
src: url('../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf') format('truetype');
188188
}
189189

190+
.badge:is(a .badge) {
191+
padding: 0px;
192+
height: 8px;
193+
width: 8px;
194+
border-radius: 4px;
195+
}
196+
197+
a .badge .badge-text {
198+
display: none;
199+
}
200+
190201
.badge {
191202
background-color: black;
192203
color: white;
@@ -215,7 +226,6 @@ html[data-theme='light'] .gallery-dark {
215226
color: rgba(176, 0, 32, 1);
216227
background-color: rgba(176, 0, 32, 0.2);
217228
border-color: rgba(176, 0, 32, 1);
218-
219229
}
220230

221231
.badge-renamed {

src/components/Card/CardTitle.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ const LEFT_SIZE = 40;
108108
/**
109109
* A component to show a title, subtitle and an avatar inside a Card.
110110
*
111-
* <div class="screenshots">
112-
* <img class="small" src="screenshots/card-title-1.png" />
113-
* </div>
114-
*
115111
* ## Usage
116112
* ```js
117113
* import * as React from 'react';

src/components/FAB/AnimatedFAB.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ export type Props = $Omit<$RemoveChildren<typeof Surface>, 'mode'> & {
105105
* @optional
106106
*/
107107
theme?: ThemeProp;
108+
/**
109+
* TestID used for testing purposes
110+
*/
108111
testID?: string;
109112
};
110113

src/components/FAB/FAB.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ export type Props = $Omit<$RemoveChildren<typeof Surface>, 'mode'> & {
133133
* @optional
134134
*/
135135
theme?: ThemeProp;
136+
/**
137+
* TestID used for testing purposes
138+
*/
136139
testID?: string;
137140
ref?: React.RefObject<View>;
138141
} & IconOrLabel;

0 commit comments

Comments
 (0)