Add HistoryCrumbs.tsx

This commit is contained in:
Jerko Steiner 2019-04-04 10:50:33 +08:00
parent b3924fa8d3
commit 3660540451
7 changed files with 120 additions and 10 deletions

View File

@ -5,3 +5,4 @@ export * from './Input'
export * from './Link'
export * from './Modal'
export * from './Redirect'
export * from './withHistory'

View File

@ -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<T extends {history: History}>(
Component: React.ComponentType<T>,
) {
class HistoryProvider extends React.PureComponent<IWithHistoryProps & T> {
render() {
const {history, location, match, children, ...props} = this.props
return (
<Component history={history} {...this.props}>
{children}
</Component>
)
}
}
return withRouter(HistoryProvider)
}

View File

@ -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<ICrumbProps> {
</BreadcrumbItem>
))}
<BreadcrumbItem>
<a>{this.props.current}</a>
<span>{this.props.current}</span>
</BreadcrumbItem>
</ul>
</Breadcrumb>

View File

@ -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[]

View File

@ -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<string, ICrumbsRoute>
}
export interface IHistoryCrumbsState {
links: ICrumbLink[]
current: string
}
export const HistoryCrumbs = withHistory(
class InnerHistoryCrumbs
extends React.PureComponent<IHistoryCrumbsProps, IHistoryCrumbsState> {
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 <Crumb links={this.state.links} current={this.state.current} />
}
},
)

View File

@ -0,0 +1,4 @@
export interface ICrumbLink {
name: string
to: string
}

View File

@ -2,3 +2,5 @@ export * from './Crumb'
export * from './CrumbsActions'
export * from './CrumbsConnector'
export * from './CrumbsReducer'
export * from './HistoryCrumbs'
export * from './ICrumbLink'