Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate component documentation #4466

Draft
wants to merge 64 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
9696cd0
first round of fixing components to be picked up by react-docgen-type…
mperrotti Apr 2, 2024
0a813c5
more fixes to appease the docgen parser
mperrotti Apr 4, 2024
c165dca
add more JSDoc comments to DataTable to generate good JSON for docs
mperrotti Apr 4, 2024
f9c73f8
docgen build script
mperrotti Apr 4, 2024
1c9d270
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Apr 4, 2024
25c7bda
fixes TextInputWithTokens prop docs
mperrotti Apr 10, 2024
e49af04
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jun 14, 2024
54892e7
fixes linting errors in components
mperrotti Jun 14, 2024
6cdcf88
fixes errors
mperrotti Jun 14, 2024
1cf0ec0
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jun 19, 2024
7eeb894
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jun 19, 2024
2169f0b
adds more prop doc coverage
mperrotti Jun 19, 2024
e73c1c9
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jun 20, 2024
12de6ac
Merge branch 'main' into mp/automate-prop-docs-passion-week-042024
mperrotti Jun 21, 2024
1d8a2f4
Merge branch 'mp/automate-prop-docs-passion-week-042024' of github.co…
mperrotti Jun 21, 2024
be24a72
adds docsId to relevant components
mperrotti Jun 21, 2024
d27318a
attempting to fix subcomponents
mperrotti Jun 21, 2024
f0aac7f
adds missing JSDoc data to components - done during audit of docgen p…
mperrotti Jun 26, 2024
7ef30d2
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jun 26, 2024
cdfd5be
beginning to fix issues causing subcomponents to be skipped by docgen
mperrotti Jun 27, 2024
af53bed
add uncommitted stuff from last commit
mperrotti Jun 27, 2024
1eff7b7
fixes missing subcomponent docs
mperrotti Jun 27, 2024
89a81fc
updates changed imports
mperrotti Jun 29, 2024
2583744
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 3, 2024
4d417e5
updates NavList exports with TrailingAction
mperrotti Jul 3, 2024
57c9580
fixes new components: NavList.TrailingAction, Announce, AriaAlert, Ar…
mperrotti Jul 3, 2024
5f20543
adds JSDoc metadata to IconButton
mperrotti Jul 3, 2024
2be3c85
fixes some more automated docs problems
mperrotti Jul 3, 2024
805b7f1
fixes issues caused by updates to exports
mperrotti Jul 3, 2024
2536e1d
formats components.json incl 'stories' data, adds ActionBar subcompon…
mperrotti Jul 5, 2024
8629a4b
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 8, 2024
944d1ec
generates component importPath, adds FeatureFlags docs data
mperrotti Jul 8, 2024
52f4687
Merge branch 'main' into mp/automate-prop-docs-passion-week-042024
mperrotti Jul 9, 2024
a8ae2c7
adds missing 'children' props, extracts values from unions
mperrotti Jul 9, 2024
e3fda71
Merge branch 'mp/automate-prop-docs-passion-week-042024' of github.co…
mperrotti Jul 9, 2024
ed42983
Merge branch 'main' into mp/automate-prop-docs-passion-week-042024
mperrotti Jul 10, 2024
55639f3
updates build script to use Docgen with our tsconfig
mperrotti Jul 10, 2024
93191c3
updates outputs to align with results of previous commit
mperrotti Jul 11, 2024
a99804b
reduce amount of changes - mostly changing imports to just use 'React…
mperrotti Jul 11, 2024
933ec32
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 11, 2024
5bed7c6
corrects aliases for CheckboxGroup.Validation and RadioGroup.Validati…
mperrotti Jul 12, 2024
cd6db28
allows us to set component 'displayName' properties directly in the c…
mperrotti Jul 12, 2024
50ab39e
Merge branch 'main' into mp/automate-prop-docs-passion-week-042024
mperrotti Jul 16, 2024
262aeeb
Merge branch 'mp/automate-prop-docs-passion-week-042024' of github.co…
mperrotti Jul 16, 2024
2b4a9f5
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 16, 2024
7de1ad0
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 25, 2024
1a649bb
updates components.json and docgen-output.json with latest prop types
mperrotti Jul 26, 2024
f34635b
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 26, 2024
55a28c6
updates component name resolver to be more reliable when dealing with…
mperrotti Jul 26, 2024
1d19be5
modifies 'ForwardRefComponent' interface so props are always included
mperrotti Jul 30, 2024
8c40539
updates exports and imports for components that were missed because t…
mperrotti Jul 31, 2024
c47aa8a
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Jul 31, 2024
af3b59a
reverts unnecessary changes
mperrotti Aug 1, 2024
9199194
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Aug 1, 2024
65e3bd0
cleans up build script for other contributors to take a look
mperrotti Aug 6, 2024
4cfd353
updates build script to override generated docs with *.docs.json data…
mperrotti Aug 8, 2024
4efe0dc
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Aug 8, 2024
f2f27bd
updates docs output after merging from main
mperrotti Aug 8, 2024
cc763ad
introduces sorting the order of props and subcomponents
mperrotti Aug 13, 2024
51ad70f
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Aug 13, 2024
cc0baf0
updates output after merging from main
mperrotti Aug 13, 2024
d3fcd12
Merge branch 'main' of github.com:primer/react into mp/automate-prop-…
mperrotti Aug 28, 2024
001fac1
updates snapshots
mperrotti Aug 28, 2024
4a32951
adds KeybindingHint, updates output JSON files with latest changes
mperrotti Aug 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"build:docs": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs",
"build:docs:preview": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs preview",
"build:components.json": "npm run build:components.json -w @primer/react",
"build:component-docs-json": "tsx packages/react/script/prop-docs/build.ts",
"lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --max-warnings=0",
"lint:fix": "npm run lint -- --fix",
"lint:md": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!**/node_modules/**\" \"!**/CHANGELOG.md\"",
Expand Down Expand Up @@ -73,6 +74,8 @@
"markdownlint-cli2": "^0.11.0",
"markdownlint-cli2-formatter-pretty": "0.0.3",
"prettier": "3.0.3",
"react-docgen": "7.0.3",
"react-docgen-typescript": "2.2.2",
"rimraf": "5.0.5",
"size-limit": "11.0.2",
"typescript": "5.3.3"
Expand Down
21 changes: 21 additions & 0 deletions packages/react/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,25 @@ module.exports = {
typescript: {
reactDocgen: 'react-docgen',
},
// typescript: {
// reactDocgen: 'react-docgen-typescript',
// reactDocgenTypescriptOptions: {
// compilerOptions: {
// allowSyntheticDefaultImports: false,
// esModuleInterop: false,
// savePropValueAsString: true,
// propFilter: (prop, component) => {
// if (prop.declarations !== undefined && prop.declarations.length > 0) {
// const hasPropAdditionalDescription = prop.declarations.find(declaration => {
// return !declaration.fileName.includes('node_modules')
// })

// return Boolean(hasPropAdditionalDescription)
// }

// return true
// },
// },
// },
// },
}
149 changes: 149 additions & 0 deletions packages/react/script/prop-docs/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
const docgen = require('react-docgen-typescript')

Check failure on line 1 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Require statement not part of import statement
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use module imports here instead of require? I see we're using tsx so that should be possible?

const globby = require('globby')

Check failure on line 2 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Require statement not part of import statement

const fs = require('node:fs')

Check failure on line 4 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Require statement not part of import statement

const docgenOptions = {
// savePropValueAsString: true,
// allowSyntheticDefaultImports might let us avoid separately importing types from React
// (e.g.: you can do `React.FC` instead of importing and using `FC` from React)
// allowSyntheticDefaultImports: true,
propFilter: (prop, _component) => {
if (prop.declarations !== undefined && prop.declarations.length > 0) {
const hasPropAdditionalDescription = prop.declarations.find(declaration => {
return !declaration.fileName.includes('node_modules')
})

return Boolean(hasPropAdditionalDescription)
}

return true
},
}

// const noPropsWhitelist = [
// 'ButtonGroup/ButtonGroup.tsx',
// {fileName: 'ConfirmationDialog/ConfirmationDialog.tsx', displayName: 'useConfirm'},
// 'UnderlineNav/LoadingCounter.tsx',
// {fileName: 'components/LiveRegion.tsx', displayName: 'LiveRegion'},
// {fileName: 'DataTable/Table.tsx', displayName: 'TableActions'},
// {fileName: 'DataTable/Table.tsx', displayName: 'TableHead'},
// {fileName: 'DataTable/Table.tsx', displayName: 'TableBody'},
// {fileName: 'DataTable/Table.tsx', displayName: 'TableRow'},
// ]

// Parse a file for docgen info
const files = globby.sync(
// Glob for testing
// [
// './packages/react/src/Avatar/*.tsx',
// './packages/react/src/DataTable/*.tsx',
// '!./packages/react/src/**/*.stories.tsx',
// '!./packages/react/src/**/*.test.tsx',
// ],
['./packages/react/src/**/*.tsx', '!./packages/react/src/**/*.stories.tsx', '!./packages/react/src/**/*.test.tsx'],
{
absolute: true,
},
)
const docgenOutput = docgen.parse(files, docgenOptions)

const printSkippedComponents = () => {
console.log('COMPONENTS SKIPPED:')

Check failure on line 52 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

files.forEach(file => {

Check failure on line 54 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Prefer for...of instead of Array.forEach
if (!docgenOutput.map(({filePath}) => filePath).includes(file)) {
console.log(file)

Check failure on line 56 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
}
})

console.log('\n')

Check failure on line 60 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
}

const printSkippedProps = () => {
console.log('PROPS NOT DOCUMENTED:')

Check failure on line 64 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

docgenOutput.forEach(({props, filePath, displayName}) => {

Check failure on line 66 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Prefer for...of instead of Array.forEach
if (Object.keys(props).length === 0) {
console.log(`${filePath} - ${displayName}`)

Check failure on line 68 in packages/react/script/prop-docs/build.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
}
})

console.log('\n')
}

const formatComponentJson = ({description, displayName, props, tags}) => {
const {alias, primerid, primerstatus, primera11yreviewed, primerstories = '', primerparentid} = tags

return {
id: primerid, // TODO: consider auto-generating an ID if one is not present by parsing `displayName`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI @broccolinisoup and I just worked up this PR and this PR that introduce a docsId field for grouping related components that have different names, eg. tooltip and tooltip_v2. We'll probably want to generate that field in this script too, although I'm not sure where the data would come from.

description,
name: primerparentid && alias ? alias : displayName,
status: primerstatus,
a11yReviewed: primera11yreviewed === 'true',
stories: primerstories.split(' '),
props: Object.keys(props).map(propName => {
const {type, required, description, defaultValue} = props[propName]

return {
name: propName,
type: type.name,
required,
description,
defaultValue: defaultValue ? defaultValue.value : null,
}
}),
}
}

const transformArray = (docgenOutputData: any[]): any[] => {
return docgenOutputData
.map(outputDatum => {
const {id, primerparentid} = outputDatum.tags

const subComponents = docgenOutputData.filter(({tags}) => tags.primerparentid && tags.primerparentid === id)

if (!primerparentid) {
return {
...formatComponentJson(outputDatum),
subcomponents: subComponents.map(formatComponentJson),
}
}
})
.filter(Boolean)
}

// write raw docgen output to file
fs.writeFile(
globby.sync('./packages/react/script/prop-docs/docgen-output.json')[0],
JSON.stringify(docgenOutput, null, 2),
err => {
if (err) {
console.error(err)
} else {
console.log(
`Components.json generated at: ${globby.sync('./packages/react/script/prop-docs/docgen-output.json')[0]}`,
)
}
},
)

// write formatted docgen output to file ([schema](https://github.com/primer/react/blob/main/packages/react/script/components-json/component.schema.json))
fs.writeFile(
globby.sync('./packages/react/script/prop-docs/components.json')[0],
JSON.stringify(transformArray(docgenOutput), null, 2),
err => {
if (err) {
console.error(err)
} else {
console.log(
`Components.json generated at: ${globby.sync('./packages/react/script/prop-docs/components.json')[0]}`,
)
}
},
)

// log debugging info

printSkippedComponents()
printSkippedProps()
Loading
Loading