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 './Button'
|
||||
export * from './IWithRouterProps'
|
||||
export * from './Input'
|
||||
export * from './Link'
|
||||
export * from './Modal'
|
||||
export * from './Redirect'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user