60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
|
|
import * as React from 'react';
|
||
|
|
import {
|
||
|
|
Link as RouterLink,
|
||
|
|
LinkProps as RouterLinkProps,
|
||
|
|
MemoryRouter,
|
||
|
|
StaticRouter,
|
||
|
|
} from 'react-router';
|
||
|
|
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||
|
|
import Button from '@mui/material/Button';
|
||
|
|
import Stack from '@mui/material/Stack';
|
||
|
|
import Link, { LinkProps } from '@mui/material/Link';
|
||
|
|
|
||
|
|
const LinkBehavior = React.forwardRef<
|
||
|
|
HTMLAnchorElement,
|
||
|
|
Omit<RouterLinkProps, 'to'> & { href: RouterLinkProps['to'] }
|
||
|
|
>((props, ref) => {
|
||
|
|
const { href, ...other } = props;
|
||
|
|
// Map href (MUI) -> to (react-router)
|
||
|
|
return <RouterLink data-testid="custom-link" ref={ref} to={href} {...other} />;
|
||
|
|
});
|
||
|
|
|
||
|
|
function Router(props: { children?: React.ReactNode }) {
|
||
|
|
const { children } = props;
|
||
|
|
if (typeof window === 'undefined') {
|
||
|
|
return <StaticRouter location="/">{children}</StaticRouter>;
|
||
|
|
}
|
||
|
|
|
||
|
|
return <MemoryRouter>{children}</MemoryRouter>;
|
||
|
|
}
|
||
|
|
|
||
|
|
const theme = createTheme({
|
||
|
|
components: {
|
||
|
|
MuiLink: {
|
||
|
|
defaultProps: {
|
||
|
|
component: LinkBehavior,
|
||
|
|
} as LinkProps,
|
||
|
|
},
|
||
|
|
MuiButtonBase: {
|
||
|
|
defaultProps: {
|
||
|
|
LinkComponent: LinkBehavior,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
export default function LinkRouterWithTheme() {
|
||
|
|
return (
|
||
|
|
<Stack spacing={1} sx={{ alignItems: 'center', typography: 'body1' }}>
|
||
|
|
<ThemeProvider theme={theme}>
|
||
|
|
<Router>
|
||
|
|
<Link href="/">Link</Link>
|
||
|
|
<Button href="/" variant="contained">
|
||
|
|
Link
|
||
|
|
</Button>
|
||
|
|
</Router>
|
||
|
|
</ThemeProvider>
|
||
|
|
</Stack>
|
||
|
|
);
|
||
|
|
}
|