Skip to content

Commit

Permalink
feat(docz): fetch data on documents
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Aug 7, 2018
1 parent 781c2bf commit 04ff0d6
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 24 deletions.
56 changes: 56 additions & 0 deletions packages/docz/src/components/AsyncComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react'
import { ReactNode, ComponentType, Component } from 'react'

import { isFn } from './Docs'

interface Props {
as: ComponentType<any>
getInitialData?: (props: any) => any
}

interface State {
loading: boolean
data: any
error: any
}

export class AsyncComponent extends Component<Props, State> {
public state = {
loading: false,
error: null,
data: {},
}

public componentDidMount(): void {
this.fetch()
}

public render(): ReactNode {
const { as: Comp = 'div', getInitialData, ...props } = this.props
const { data, loading, error } = this.state

return <Comp {...props} data={{ ...data, loading, error }} />
}

private async fetch(): Promise<void> {
const { getInitialData } = this.props

if (getInitialData && isFn(getInitialData)) {
this.setState({ loading: true })
try {
const data = await getInitialData(this.props)
this.setState({
data,
error: null,
loading: false,
})
} catch (error) {
this.setState({
error,
data: {},
loading: false,
})
}
}
}
}
67 changes: 67 additions & 0 deletions packages/docz/src/components/AsyncRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as React from 'react'
import { SFC } from 'react'
import { withMDXComponents } from '@mdx-js/tag/dist/mdx-provider'
import importedComponent from 'react-imported-component'

import { ImportMap, EntryMap } from '../state'
import { ComponentsMap } from './DocPreview'
import { AsyncComponent } from './AsyncComponent'

interface AsyncRouteProps {
components: ComponentsMap
path: string
imports: ImportMap
entries: EntryMap
}

export const AsyncRoute: SFC<AsyncRouteProps> = ({
components,
path,
imports,
entries,
...routeProps
}) => {
const Page: any = components.page
const LoadingComponent: any = components.loading
const entry = entries && entries[path]
const props = { ...routeProps, doc: entry }

const loadImport = async () => {
const { default: Component, getInitialData } = await imports[path]()

const ExportedComponent: any = (props: any) => <Component {...props} />
ExportedComponent.getInitialData = getInitialData
return ExportedComponent
}

const Component = withMDXComponents(
importedComponent(loadImport, {
LoadingComponent,
render(Component: any, state, defaultProps: any): React.ReactNode {
const { history, match, location, doc } = defaultProps
const { LoadingComponent: Loading } = defaultProps
const props = { history, match, location, doc }

if (state === 'done') {
return (
<AsyncComponent
{...props}
as={Component}
getInitialData={Component.getInitialData}
/>
)
}

return <Loading {...props} />
},
})
)

return Page ? (
<Page {...props}>
<Component {...props} />
</Page>
) : (
<Component {...props} />
)
}
39 changes: 16 additions & 23 deletions packages/docz/src/components/DocPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as React from 'react'
import { Fragment, SFC, ComponentType as CT } from 'react'
import { Switch, Route, RouteComponentProps } from 'react-router-dom'
import { withMDXComponents } from '@mdx-js/tag/dist/mdx-provider'
import { MDXProvider } from '@mdx-js/tag'
import importedComponent from 'react-imported-component'

import { state, State, Entry, EntryMap } from '../state'
import { themeContext } from '../theme'
import { AsyncRoute } from './AsyncRoute'

export type PageProps = RouteComponentProps<any> & {
doc: Entry
Expand Down Expand Up @@ -82,7 +81,6 @@ export const DocPreview: SFC<DocPreviewProps> = ({
...themeComponents,
}

const Page: any = components.page
const NotFound: any = components.notFound
const LoadingComponent: any = components.loading

Expand All @@ -96,28 +94,23 @@ export const DocPreview: SFC<DocPreviewProps> = ({
{(entries: EntryMap) => (
<Switch>
{Object.keys(imports).map(path => {
const entry = entries && entries[path]
const AsyncComponent = withMDXComponents(
importedComponent(imports[path], { LoadingComponent })
)
const entry = entries[path]

return (
entry && (
<Route
exact
key={entry.id}
path={entry.route}
render={props =>
Page ? (
<Page {...props} doc={entry}>
<AsyncComponent />
</Page>
) : (
<AsyncComponent {...props} />
)
}
/>
)
<Route
exact
key={entry.id}
path={entry.route}
render={props => (
<AsyncRoute
{...props}
path={path}
entries={entries}
imports={imports}
components={components}
/>
)}
/>
)
})}
{NotFound && <Route component={NotFound} />}
Expand Down
5 changes: 4 additions & 1 deletion packages/docz/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type MSXComponent = CT<{

export interface MSXImport {
default: MSXComponent
getInitialData?: (props: any) => any
}

export interface Heading {
Expand Down Expand Up @@ -41,8 +42,10 @@ export interface Config {
version: string | null
}

type Import = () => Promise<MSXImport>

export type EntryMap = Record<string, Entry>
export type ImportMap = Record<string, () => Promise<MSXImport>>
export type ImportMap = Record<string, Import>
export type TransformFn = (config: Config) => Config

export interface State {
Expand Down

0 comments on commit 04ff0d6

Please sign in to comment.