Skip to content

Commit

Permalink
feat: add hook to find docgen props (#1371)
Browse files Browse the repository at this point in the history
* feat: setup test case

* feat: add component props hook

* feat: remove test example
  • Loading branch information
mickaelzhang committed Jan 31, 2020
1 parent 44edc68 commit 8fffa26
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 43 deletions.
48 changes: 5 additions & 43 deletions core/docz/src/components/Props.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import * as React from 'react'
import { createElement, SFC, ComponentType, useMemo } from 'react'
import { assoc, first, get, mapValues, kebabCase } from 'lodash/fp'
import { SFC, ComponentType } from 'react'
import { get } from 'lodash/fp'
import capitalize from 'capitalize'
import marksy from 'marksy'
import { pascalCase } from 'pascal-case'

import { doczState } from '../state'
import { useComponents } from '../hooks'
import { useComponents, useComponentProps } from '../hooks'
import { humanize } from '../utils/humanize-prop'

export interface EnumValue {
Expand Down Expand Up @@ -111,48 +108,13 @@ export const Props: SFC<PropsProps> = ({
...rest
}) => {
const components = useComponents()
const { props: stateProps } = React.useContext(doczState.context)
const PropsComponent = components.props
const filename = get('__filemeta.filename', component)
const fileName = get('__filemeta.filename', component)
const filemetaName = get('__filemeta.name', component)
const componentName =
filemetaName || get('displayName', component) || get('name', component)

const componentMatcher = (componentName: string, item: any) => {
const matchingPatterns = [
filename,
`/${componentName}.`,
`/${kebabCase(componentName)}.`,
`/${pascalCase(componentName)}.`,
]
return !!matchingPatterns.find(pattern => item.key.includes(pattern))
}

const found =
stateProps &&
stateProps.length > 0 &&
stateProps.find(item => componentMatcher(componentName, item))

const value = get('value', found) || []
const firstDefinition = first(value)
const definition = value.find((i: any) => i.displayName === componentName)

const compile = useMemo(
() => marksy({ createElement, elements: components }),
[components]
)

const props = useMemo(() => {
const props = get('props', definition || firstDefinition)
const parseDescs = mapValues((prop: any) => {
const desc = get('description', prop)
return !desc ? prop : assoc('description', compile(desc).tree, prop)
})

return parseDescs(props)
}, [compile, definition || firstDefinition])

if (!props) return null
const props = useComponentProps({ componentName, fileName })
if (!PropsComponent) return null
return (
<PropsComponent
Expand Down
1 change: 1 addition & 0 deletions core/docz/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './useComponents'
export { useConfig, UseConfigObj } from './useConfig'
export { useComponentProps } from './useComponentProps'
export { useCurrentDoc } from './useCurrentDoc'
export { useDataServer } from './useDataServer'
export { useDocs } from './useDocs'
Expand Down
56 changes: 56 additions & 0 deletions core/docz/src/hooks/useComponentProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createElement, useContext, useMemo } from 'react'
import { assoc, first, get, mapValues, kebabCase } from 'lodash/fp'
import { pascalCase } from 'pascal-case'
import marksy from 'marksy'

import { useComponents } from '../hooks'
import { doczState } from '../state'

interface UseComponentPropsParams {
componentName: string
fileName: string
}

export const useComponentProps = ({
componentName,
fileName,
}: UseComponentPropsParams) => {
const components = useComponents()
const { props: stateProps } = useContext(doczState.context)

const componentMatcher = (componentName: string, item: any) => {
const matchingPatterns = [
fileName,
`/${componentName}.`,
`/${kebabCase(componentName)}.`,
`/${pascalCase(componentName)}.`,
]
return !!matchingPatterns.find(pattern => item.key.includes(pattern))
}

const found =
stateProps &&
stateProps.length > 0 &&
stateProps.find(item => componentMatcher(componentName, item))

const value = get('value', found) || []
const firstDefinition = first(value)
const definition = value.find((i: any) => i.displayName === componentName)

const compile = useMemo(
() => marksy({ createElement, elements: components }),
[components]
)

const props = useMemo(() => {
const props = get('props', definition || firstDefinition)
const parseDescs = mapValues((prop: any) => {
const desc = get('description', prop)
return !desc ? prop : assoc('description', compile(desc).tree, prop)
})

return parseDescs(props)
}, [compile, definition || firstDefinition])

return props
}

0 comments on commit 8fffa26

Please sign in to comment.