docs: generate documentation for UI components (#5849)
* added tool to generate spec files for React components * use typedoc for missing descriptions and types * improvements and fixes * improvements * added doc comments for half of the components * add custom resolver + more doc comments * added all tsdocs * general improvements * add specs to UI docs * added github action * remove unnecessary api route * Added readme for react-docs-generator * remove comment * Update packages/design-system/ui/src/components/currency-input/currency-input.tsx Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com> * remove description of aria fields + add generate script --------- Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com>
This commit is contained in:
co-authored by
Kasper Fabricius Kristensen
parent
edc49bfe1d
commit
245e5c9a69
@@ -0,0 +1,105 @@
|
||||
import { visitors } from "@babel/traverse"
|
||||
import { utils, builtinResolvers, FileState, NodePath } from "react-docgen"
|
||||
import { ComponentNodePath } from "react-docgen/dist/resolver/index.js"
|
||||
import TypedocManager from "../classes/typedoc-manager.js"
|
||||
|
||||
type State = {
|
||||
foundDefinitions: Set<ComponentNodePath>
|
||||
}
|
||||
/**
|
||||
* This resolver extends react-docgen's FindAllDefinitionsResolver
|
||||
* + adds the ability to resolve variable components such as:
|
||||
*
|
||||
* ```tsx
|
||||
* const Value = SelectPrimitive.Value
|
||||
* Value.displayName = "Select.Value"
|
||||
* ```
|
||||
*/
|
||||
export default class CustomResolver
|
||||
implements builtinResolvers.FindAllDefinitionsResolver
|
||||
{
|
||||
private typedocManager: TypedocManager
|
||||
constructor(typedocManager: TypedocManager) {
|
||||
this.typedocManager = typedocManager
|
||||
}
|
||||
resolve(file: FileState): ComponentNodePath[] {
|
||||
const state = {
|
||||
foundDefinitions: new Set<ComponentNodePath>(),
|
||||
}
|
||||
file.traverse(
|
||||
visitors.explode({
|
||||
FunctionDeclaration: { enter: this.statelessVisitor },
|
||||
FunctionExpression: { enter: this.statelessVisitor },
|
||||
ObjectMethod: { enter: this.statelessVisitor },
|
||||
ArrowFunctionExpression: { enter: this.statelessVisitor },
|
||||
ClassExpression: { enter: this.classVisitor },
|
||||
ClassDeclaration: { enter: this.classVisitor },
|
||||
VariableDeclaration: {
|
||||
enter: (path, state: State) => {
|
||||
const found = path.node.declarations.some((declaration) => {
|
||||
if (
|
||||
"name" in declaration.id &&
|
||||
this.typedocManager.isReactComponent(declaration.id.name) &&
|
||||
declaration.init
|
||||
) {
|
||||
const init = path.get("declarations")[0].get("init")
|
||||
if (init.isMemberExpression()) {
|
||||
state.foundDefinitions.add(
|
||||
path as unknown as ComponentNodePath
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
if (found) {
|
||||
return path.skip()
|
||||
}
|
||||
},
|
||||
},
|
||||
CallExpression: {
|
||||
enter: (path, state: State) => {
|
||||
const argument = path.get("arguments")[0]
|
||||
if (!argument) {
|
||||
return
|
||||
}
|
||||
if (utils.isReactForwardRefCall(path)) {
|
||||
// If the the inner function was previously identified as a component
|
||||
// replace it with the parent node
|
||||
const inner = utils.resolveToValue(argument) as ComponentNodePath
|
||||
state.foundDefinitions.delete(inner)
|
||||
state.foundDefinitions.add(path)
|
||||
// Do not traverse into arguments
|
||||
return path.skip()
|
||||
} else if (utils.isReactCreateClassCall(path)) {
|
||||
const resolvedPath = utils.resolveToValue(argument)
|
||||
if (resolvedPath.isObjectExpression()) {
|
||||
state.foundDefinitions.add(resolvedPath)
|
||||
}
|
||||
// Do not traverse into arguments
|
||||
return path.skip()
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
state
|
||||
)
|
||||
return Array.from(state.foundDefinitions)
|
||||
}
|
||||
|
||||
classVisitor(path: NodePath, state: State) {
|
||||
if (utils.isReactComponentClass(path)) {
|
||||
utils.normalizeClassDefinition(path)
|
||||
state.foundDefinitions.add(path)
|
||||
}
|
||||
path.skip()
|
||||
}
|
||||
statelessVisitor(path: NodePath, state: State) {
|
||||
if (utils.isStatelessComponent(path)) {
|
||||
state.foundDefinitions.add(path)
|
||||
}
|
||||
path.skip()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user