Skip to content

Commit

Permalink
feat: split router logic from theme
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Jan 22, 2019
1 parent 4162a1c commit a9c26e6
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 142 deletions.
2 changes: 0 additions & 2 deletions core/docz-core/src/bundler/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ export const createConfig = (args: Args, env: Env) => async (hooks: Hooks) => {
.add('.mdx')
.end()

config.resolve.alias.set('~db', paths.db)
config.resolve.alias.set('~imports', paths.importsJs)
config.resolve.alias.set('react-native$', 'react-native-web')

const inYarnWorkspaces = __dirname.includes('/docz/core/docz-core')
Expand Down
9 changes: 8 additions & 1 deletion core/docz-core/templates/root.tpl.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from 'react'
import { Router, Routes } from 'docz'
import { hot } from 'react-hot-loader'
import Theme from '<%- theme %>'

import { imports } from './imports'
import database from './db.json'
<% if (wrapper) {%>import Wrapper from '<%- wrapper %>'<%}%>

const Root = () => (
<Theme <% if (wrapper) {%>wrapper={Wrapper}<%}%> />
<Theme <% if (wrapper) {%>wrapper={Wrapper}<%}%> db={database}>
<Router>
<Routes imports={imports} />
</Router>
</Theme>
)

export default hot(module)(Root)
58 changes: 27 additions & 31 deletions core/docz-theme-default/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SFC } from 'react'
import { theme, DocPreview, ThemeConfig } from 'docz'
import { ThemeProvider } from 'emotion-theming'
import { jsx } from '@emotion/core'
Expand All @@ -8,39 +9,34 @@ import { config } from './config'
import * as components from './components/ui'
import * as modes from './styles/modes'

const Theme = () => (
const componentsMap = {
page: components.Page,
notFound: components.NotFound,
render: components.Render,
blockquote: components.Blockquote,
h1: components.H1,
h2: components.H2,
h3: components.H3,
h4: components.H4,
h5: components.H5,
h6: components.H6,
hr: components.Hr,
ul: components.UnorderedList,
ol: components.OrderedList,
p: components.Paragraph,
a: components.Link,
inlineCode: components.InlineCode,
loading: components.Loading,
table: components.Table,
pre: components.Pre,
tooltip: components.Tooltip,
}

const Theme: SFC = ({ children }) => (
<ThemeConfig>
{config => (
<ThemeProvider
theme={prev => ({
...prev,
docz: config.themeConfig,
})}
>
<DocPreview
components={{
page: components.Page,
notFound: components.NotFound,
render: components.Render,
blockquote: components.Blockquote,
h1: components.H1,
h2: components.H2,
h3: components.H3,
h4: components.H4,
h5: components.H5,
h6: components.H6,
hr: components.Hr,
ul: components.UnorderedList,
ol: components.OrderedList,
p: components.Paragraph,
a: components.Link,
inlineCode: components.InlineCode,
loading: components.Loading,
table: components.Table,
pre: components.Pre,
tooltip: components.Tooltip,
}}
/>
<ThemeProvider theme={prev => ({ ...prev, docz: config.themeConfig })}>
<DocPreview components={componentsMap}>{children}</DocPreview>
</ThemeProvider>
)}
</ThemeConfig>
Expand Down
2 changes: 0 additions & 2 deletions core/docz/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
"@mdx-js/tag": "^0.16.6",
"@sindresorhus/slugify": "^0.8.0",
"array-sort": "^1.0.0",
"callbag-observe": "^1.0.0",
"callbag-subject": "^1.0.2",
"capitalize": "^2.0.0",
"deepmerge": "^3.1.0",
"docz-core": "^0.13.5",
Expand Down
4 changes: 1 addition & 3 deletions core/docz/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ import { config } from 'docz-rollup'
export default config({
input: 'src/index.ts',
external: id =>
id === '~db' ||
id === '~imports' ||
(!id.startsWith('\0') && !id.startsWith('.') && !id.startsWith('/')),
!id.startsWith('\0') && !id.startsWith('.') && !id.startsWith('/'),
})
15 changes: 11 additions & 4 deletions core/docz/src/components/AsyncRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { EntryMap } from '../state'
import { ComponentsMap } from './DocPreview'
import { AsyncComponent } from './AsyncComponent'

export async function loadFromImports(path: string): Promise<SFC<any>> {
export type Imports = Record<string, () => Promise<any>>
export async function loadFromImports(
path: string,
imports: Imports
): Promise<SFC<any>> {
// tslint:disable-next-line
const { imports } = await import('~imports')
const { default: Component, getInitialData } = await imports[path]()
const ExportedComponent: SFC<any> = props => (
<AsyncComponent
Expand All @@ -22,9 +25,13 @@ export async function loadFromImports(path: string): Promise<SFC<any>> {
return withMDXComponents(ExportedComponent)
}

export const loadRoute: any = (path: string, LoadingComponent: any) => {
export const loadRoute: any = (
path: string,
imports: Imports,
LoadingComponent: any
) => {
const opts: any = { LoadingComponent }
return importedComponent(async () => loadFromImports(path), opts)
return importedComponent(async () => loadFromImports(path, imports), opts)
}

interface AsyncRouteProps {
Expand Down
60 changes: 10 additions & 50 deletions core/docz/src/components/DocPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import * as React from 'react'
import { Fragment, SFC, ComponentType as CT } from 'react'
import { Switch, Route, RouteComponentProps } from 'react-router-dom'
import { RouteComponentProps } from 'react-router-dom'
import { MDXProvider } from '@mdx-js/tag'
import { get } from 'lodash/fp'

import { AsyncRoute, loadRoute } from './AsyncRoute'
import { state, Entry } from '../state'
import { Entry } from '../state'

export type PageProps = RouteComponentProps<any> & {
doc: Entry
Expand Down Expand Up @@ -46,27 +44,23 @@ export interface ComponentsMap {
[key: string]: any
}

export type NotFoundComponent = CT<RouteComponentProps<any>>
const DefaultNotFound: NotFoundComponent = () => <Fragment>Not found</Fragment>
const DefaultLoading: SFC = () => <Fragment>Loading</Fragment>

export const Identity: SFC<any> = ({ children }) => (
<Fragment>{children}</Fragment>
)

export const DefaultRender: RenderComponent = ({ component, code }) => (
const DefaultPage: SFC<any> = ({ children }) => <Fragment>{children}</Fragment>
const DefaultRender: RenderComponent = ({ component, code }) => (
<Fragment>
{component}
{code}
</Fragment>
)

export type NotFoundComponent = CT<RouteComponentProps<any>>
const DefaultNotFound: NotFoundComponent = () => <Fragment>Not found</Fragment>

const defaultComponents: ComponentsMap = {
loading: DefaultLoading,
render: DefaultRender,
notFound: DefaultNotFound,
page: Identity,
page: DefaultPage,
}

export interface DocPreviewProps {
Expand All @@ -75,45 +69,11 @@ export interface DocPreviewProps {

export const DocPreview: SFC<DocPreviewProps> = ({
components: themeComponents = {},
children,
}) => {
const components = {
...defaultComponents,
...themeComponents,
}

const NotFound: any = components.notFound

return (
<MDXProvider components={components}>
{state.get(({ entries }) => {
if (!entries) return null
return (
<Switch>
{Object.keys(entries).map(path => {
const entry = get(path, entries)
const props = { path, entries, components }
const component: any = loadRoute(path, components.loading)

component.preload()
return (
<Route
exact
key={entry.id}
path={entry.route}
render={routeProps => (
<AsyncRoute
{...routeProps}
{...props}
asyncComponent={component}
/>
)}
/>
)
})}
{NotFound && <Route component={NotFound} />}
</Switch>
)
})}
<MDXProvider components={{ ...defaultComponents, ...themeComponents }}>
{children}
</MDXProvider>
)
}
22 changes: 22 additions & 0 deletions core/docz/src/components/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react'
import { SFC } from 'react'
import { HashRouter, BrowserRouter } from 'react-router-dom'
import { StaticRouterProps } from 'react-router'

import { ScrollToTop } from '../utils/ScrollToTop'

declare var DOCZ_BASE_URL: string
declare var DOCZ_HASH_ROUTER: boolean

const BaseRouter: SFC<StaticRouterProps> = (props: any) =>
Boolean(DOCZ_HASH_ROUTER) ? (
<HashRouter {...props} />
) : (
<BrowserRouter {...props} />
)

export const Router: SFC = ({ children }) => (
<BaseRouter basename={DOCZ_BASE_URL}>
<ScrollToTop>{children}</ScrollToTop>
</BaseRouter>
)
54 changes: 54 additions & 0 deletions core/docz/src/components/Routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react'
import { Fragment, SFC } from 'react'
import { Switch, Route } from 'react-router-dom'
import { withMDXComponents } from '@mdx-js/tag/dist/mdx-provider'
import { get } from 'lodash/fp'

import { state } from '../state'
import { AsyncRoute, loadRoute, Imports } from './AsyncRoute'
import { ComponentsMap } from './DocPreview'

export interface RoutesProps {
components: ComponentsMap
imports: Imports
}

export const Routes: SFC = withMDXComponents(
({ components, imports }: RoutesProps) => (
<Fragment>
{state.get(({ entries }) => {
if (!entries || !components) return null

const NotFound: any = components.notFound
const Loading: any = components.loading

return (
<Switch>
{Object.keys(entries).map(path => {
const entry = get(path, entries)
const props = { path, entries, components }
const component: any = loadRoute(path, imports, Loading)

component.preload()
return (
<Route
exact
key={entry.id}
path={entry.route}
render={routeProps => (
<AsyncRoute
{...routeProps}
{...props}
asyncComponent={component}
/>
)}
/>
)
})}
{NotFound && <Route component={NotFound} />}
</Switch>
)
})}
</Fragment>
)
)
14 changes: 6 additions & 8 deletions core/docz/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
export { theme } from './theme'
export { Entry, MenuItem } from './state'
export { Docs, DocsRenderProps } from './components/Docs'
export { Link, LinkProps } from './components/Link'
export { Menu, MenuRenderProps } from './components/Menu'
export { Playground } from './components/Playground'
export { PropsTable } from './components/PropsTable'
export { ThemeConfig } from './components/ThemeConfig'
export {
DocPreview,
PageProps,
RenderComponent,
RenderComponentProps,
} from './components/DocPreview'
export { Router } from './components/Router'
export { Routes } from './components/Routes'
export * from './components/DocPreview'

export { theme } from './theme'
export { Entry, MenuItem } from './state'
5 changes: 4 additions & 1 deletion core/docz/src/state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ export interface Config {
export type EntryMap = Record<string, Entry>
export type TransformFn = (config: ThemeConfig) => ThemeConfig

export interface State {
export interface Database {
config?: Config
entries?: EntryMap
props?: any
}

export interface State extends Database {
themeConfig?: ThemeConfig
transform?: TransformFn
}
Expand Down
Loading

0 comments on commit a9c26e6

Please sign in to comment.