Add Link (ContextLink)
This commit is contained in:
parent
d5cb6b92b6
commit
71f7687ab9
8
packages/client/src/components/IWithRouterProps.ts
Normal file
8
packages/client/src/components/IWithRouterProps.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import {match as Match} from 'react-router'
|
||||||
|
import {History, Location} from 'history'
|
||||||
|
|
||||||
|
export interface IWithRouterProps<MatchProps = unknown> {
|
||||||
|
history: History
|
||||||
|
location: Location
|
||||||
|
match: Match<MatchProps>
|
||||||
|
}
|
||||||
49
packages/client/src/components/Link.test.tsx
Normal file
49
packages/client/src/components/Link.test.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {MemoryRouter} from 'react-router'
|
||||||
|
import {Route} from 'react-router-dom'
|
||||||
|
import {Link} from './Link'
|
||||||
|
import {TestUtils} from '../test-utils'
|
||||||
|
|
||||||
|
describe('Link', () => {
|
||||||
|
|
||||||
|
const t = new TestUtils()
|
||||||
|
|
||||||
|
function render(
|
||||||
|
to: string,
|
||||||
|
routePath = '/test',
|
||||||
|
routerEntry = '/test',
|
||||||
|
) {
|
||||||
|
return t.render(
|
||||||
|
<MemoryRouter initialEntries={[routerEntry]}>
|
||||||
|
<Route
|
||||||
|
path={routePath}
|
||||||
|
render={() =>
|
||||||
|
<div>
|
||||||
|
<Link to={to}>Link Text</Link>
|
||||||
|
</div>}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should set href to value', () => {
|
||||||
|
const {node} = render('/my/link')
|
||||||
|
const a = node.querySelector('a') as HTMLElement
|
||||||
|
expect(a.tagName).toEqual('A')
|
||||||
|
expect(a.getAttribute('href')).toEqual('/my/link')
|
||||||
|
expect(a.textContent).toEqual('Link Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should format url to matched props', () => {
|
||||||
|
const {node} = render(
|
||||||
|
'/my/:oneId/link/:twoId',
|
||||||
|
'/one/:oneId/two/:twoId',
|
||||||
|
'/one/1/two/2',
|
||||||
|
)
|
||||||
|
const a = node.querySelector('a') as HTMLElement
|
||||||
|
expect(a.tagName).toEqual('A')
|
||||||
|
expect(a.getAttribute('href')).toEqual('/my/1/link/2')
|
||||||
|
expect(a.textContent).toEqual('Link Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
35
packages/client/src/components/Link.tsx
Normal file
35
packages/client/src/components/Link.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {History, Location} from 'history'
|
||||||
|
import {IWithRouterProps} from './IWithRouterProps'
|
||||||
|
import {Link as RouterLink, LinkProps} from 'react-router-dom'
|
||||||
|
import {URLFormatter} from '@rondo/common'
|
||||||
|
import {withRouter} from 'react-router'
|
||||||
|
|
||||||
|
interface ILinkProps
|
||||||
|
extends IWithRouterProps<Record<string, string>> {
|
||||||
|
readonly to: string
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContextLink extends React.PureComponent<ILinkProps> {
|
||||||
|
protected readonly urlFormatter = new URLFormatter()
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
history,
|
||||||
|
location,
|
||||||
|
match,
|
||||||
|
to,
|
||||||
|
children,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const href = this.urlFormatter.format(to, match.params)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RouterLink to={href}>
|
||||||
|
{children}
|
||||||
|
</RouterLink>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Link = withRouter(ContextLink)
|
||||||
@ -1,5 +1,7 @@
|
|||||||
export * from './Button'
|
|
||||||
// export * from './Component'
|
// export * from './Component'
|
||||||
|
export * from './Button'
|
||||||
|
export * from './IWithRouterProps'
|
||||||
export * from './Input'
|
export * from './Input'
|
||||||
|
export * from './Link'
|
||||||
export * from './Modal'
|
export * from './Modal'
|
||||||
export * from './Redirect'
|
export * from './Redirect'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user