diff --git a/packages/client/src/components/index.ts b/packages/client/src/components/index.ts index 96006b2..a4e24d8 100644 --- a/packages/client/src/components/index.ts +++ b/packages/client/src/components/index.ts @@ -5,3 +5,4 @@ export * from './Input' export * from './Link' export * from './Modal' export * from './Redirect' +export * from './withHistory' diff --git a/packages/client/src/components/withHistory.tsx b/packages/client/src/components/withHistory.tsx new file mode 100644 index 0000000..a2c15fb --- /dev/null +++ b/packages/client/src/components/withHistory.tsx @@ -0,0 +1,26 @@ +import {History, Location} from 'history' +import {withRouter, match as Match} from 'react-router' +import React from 'react' + +export interface IWithHistoryProps { + history: History + location: Location + match: Match +} + +export function withHistory( + Component: React.ComponentType, +) { + class HistoryProvider extends React.PureComponent { + render() { + const {history, location, match, children, ...props} = this.props + return ( + + {children} + + ) + } + } + + return withRouter(HistoryProvider) +} diff --git a/packages/client/src/crumbs/Crumb.tsx b/packages/client/src/crumbs/Crumb.tsx index b560221..47c6154 100644 --- a/packages/client/src/crumbs/Crumb.tsx +++ b/packages/client/src/crumbs/Crumb.tsx @@ -1,12 +1,10 @@ import React from 'react' import {Breadcrumb, BreadcrumbItem} from 'bloomer' import {Link} from 'react-router-dom' +import {ICrumbLink} from './ICrumbLink' export interface ICrumbProps { - links: Array<{ - name: string - to: string - }> + links: ICrumbLink[] current: string } @@ -24,7 +22,7 @@ export class Crumb extends React.PureComponent { ))} - {this.props.current} + {this.props.current} diff --git a/packages/client/src/crumbs/CrumbsActions.ts b/packages/client/src/crumbs/CrumbsActions.ts index 8e99e90..8007b60 100644 --- a/packages/client/src/crumbs/CrumbsActions.ts +++ b/packages/client/src/crumbs/CrumbsActions.ts @@ -1,9 +1,5 @@ import {TGetAction, IAction} from '../actions' - -export interface ICrumbLink { - name: string - to: string -} +import {ICrumbLink} from './ICrumbLink' export interface ICrumbs { links: ICrumbLink[] diff --git a/packages/client/src/crumbs/HistoryCrumbs.tsx b/packages/client/src/crumbs/HistoryCrumbs.tsx new file mode 100644 index 0000000..51a4fe1 --- /dev/null +++ b/packages/client/src/crumbs/HistoryCrumbs.tsx @@ -0,0 +1,83 @@ +import React from 'react' +import {Crumb} from './Crumb' +import {History, Location} from 'history' +import {ICrumbLink} from './ICrumbLink' +import {match as Match, matchPath, withRouter} from 'react-router' +import {withHistory} from '../components' + +export interface ICrumbsRoute { + exact?: boolean + links: ICrumbLink[] + current: string +} + +export interface IHistoryCrumbsProps { + history: History + routes: Record +} + +export interface IHistoryCrumbsState { + links: ICrumbLink[] + current: string +} + +export const HistoryCrumbs = withHistory( + class InnerHistoryCrumbs + extends React.PureComponent { + unlisten!: () => void + + constructor(props: IHistoryCrumbsProps) { + super(props) + this.state = { + links: [], + current : '', + } + } + + componentWillMount() { + this.handleChange(this.props.history.location.pathname) + this.unlisten = this.props.history.listen((location, action) => { + this.handleChange(this.props.history.location.pathname) + }) + } + + componentWillUnmount() { + this.unlisten() + } + + handleChange(path: string) { + const {routes} = this.props + + let found: null | {match: Match<{}>, route: ICrumbsRoute} = null + + Object.keys(routes).some(route => { + const match = matchPath(path, { + path: route, + exact: routes[route].exact, + }) + if (match) { + found = {match, route: routes[route]} + return true + } + return false + }) + + if (!found) { + this.setState({ + links: [], + current: '', + }) + return + } + + this.setState({ + links: found!.route.links, + current: found!.route.current, + }) + } + + render() { + return + } + }, +) diff --git a/packages/client/src/crumbs/ICrumbLink.ts b/packages/client/src/crumbs/ICrumbLink.ts new file mode 100644 index 0000000..0636348 --- /dev/null +++ b/packages/client/src/crumbs/ICrumbLink.ts @@ -0,0 +1,4 @@ +export interface ICrumbLink { + name: string + to: string +} diff --git a/packages/client/src/crumbs/index.ts b/packages/client/src/crumbs/index.ts index 1653ea0..9fd8a9b 100644 --- a/packages/client/src/crumbs/index.ts +++ b/packages/client/src/crumbs/index.ts @@ -2,3 +2,5 @@ export * from './Crumb' export * from './CrumbsActions' export * from './CrumbsConnector' export * from './CrumbsReducer' +export * from './HistoryCrumbs' +export * from './ICrumbLink'