-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: update root to use suspense * chore: update Map Layout * chore: styled map tabs * chore: testing * scaffold test * chore: adds routing tests * chore: update tabs to remove console logs * chore: update index route to redirect in useLayoutEffect * chore: remove unnecessary styling * chore: padding * chore: removed TanStackRouterDevtool * chore: remove import * chore: remove dev tool
- Loading branch information
Showing
12 changed files
with
221 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,6 +86,7 @@ const theme = createTheme({ | |
}, | ||
}, | ||
}, | ||
spacing: 1, | ||
}) | ||
|
||
export { theme } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined' | ||
import PostAddIcon from '@mui/icons-material/PostAdd' | ||
import SettingsIcon from '@mui/icons-material/Settings' | ||
import Tab from '@mui/material/Tab' | ||
import MuiTabs from '@mui/material/Tabs' | ||
import { styled } from '@mui/material/styles' | ||
import { useLocation, useNavigate } from '@tanstack/react-router' | ||
import { defineMessages, useIntl } from 'react-intl' | ||
|
||
import type { FileRoutesById } from '../routeTree.gen' | ||
import { Text } from './Text' | ||
|
||
const m = defineMessages({ | ||
setting: { | ||
id: 'tabBar.label.settings', | ||
defaultMessage: 'Settings', | ||
}, | ||
about: { | ||
id: 'tabBar.label.about', | ||
defaultMessage: 'About', | ||
}, | ||
}) | ||
|
||
const MapTabStyled = styled(MapTab)({ | ||
width: 60, | ||
'& MuiButtonBase.Mui-selected': { color: '#000' }, | ||
}) | ||
|
||
export const Tabs = () => { | ||
const navigate = useNavigate() | ||
const { formatMessage } = useIntl() | ||
const location = useLocation() | ||
return ( | ||
<MuiTabs | ||
sx={{ | ||
pb: 20, | ||
pt: 20, | ||
'& .MuiTabs-flexContainer': { | ||
height: '100%', | ||
}, | ||
}} | ||
onChange={(_, value) => navigate({ to: value as MapTabRoute })} | ||
orientation="vertical" | ||
value={location.pathname} | ||
TabIndicatorProps={{ style: { backgroundColor: 'transparent' } }} | ||
> | ||
<MapTabStyled | ||
data-testid="tab-observation" | ||
icon={<PostAddIcon />} | ||
value={'/tab1'} | ||
/> | ||
{/* This is needed to properly space the items. Originally used a div, but was causing console errors as the Parent component passes it props, which were invalid for non-tab components */} | ||
<Tab disabled={true} sx={{ flex: 1 }} /> | ||
|
||
<MapTabStyled | ||
icon={<SettingsIcon />} | ||
label={ | ||
<Text style={{ fontSize: 10 }} kind="title"> | ||
{formatMessage(m.setting)} | ||
</Text> | ||
} | ||
value={'/tab2'} | ||
/> | ||
<MapTabStyled | ||
icon={<InfoOutlinedIcon />} | ||
label={ | ||
<Text style={{ fontSize: 10 }} kind="title"> | ||
{formatMessage(m.about)} | ||
</Text> | ||
} | ||
value={'/tab2'} | ||
/> | ||
</MuiTabs> | ||
) | ||
} | ||
|
||
type TabProps = React.ComponentProps<typeof Tab> | ||
|
||
type MapTabRoute = { | ||
[K in keyof FileRoutesById]: K extends `${'/(MapTabs)/_Map'}${infer Rest}` | ||
? Rest extends '' | ||
? never | ||
: `${Rest}` | ||
: never | ||
}[keyof FileRoutesById] | ||
|
||
type MapTabProps = Omit<TabProps, 'value'> & { value: MapTabRoute } | ||
|
||
function MapTab(props: MapTabProps) { | ||
return <Tab {...props} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,54 @@ | ||
import type { ReactNode } from 'react' | ||
import { | ||
RouterProvider, | ||
createRootRoute, | ||
createRoute, | ||
createRouter, | ||
} from '@tanstack/react-router' | ||
import { render, screen } from '@testing-library/react' | ||
import { expect, test, vi } from 'vitest' | ||
import { expect, test } from 'vitest' | ||
|
||
import { IntlProvider } from '../../contexts/IntlContext' | ||
import { MapLayout } from './_Map' | ||
|
||
vi.mock('@tanstack/react-router', () => ({ | ||
useNavigate: vi.fn(() => { | ||
return { navigate: vi.fn() } | ||
}), | ||
createFileRoute: vi.fn(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
return (options: any) => ({ component: options.component }) // Mocked implementation | ||
}), | ||
Outlet: () => <div>Mocked Outlet</div>, | ||
})) | ||
|
||
test('renders something in the jsdom', () => { | ||
render(<MapLayout />) | ||
expect(screen).toBeDefined() | ||
const rootRoute = createRootRoute({}) | ||
|
||
const Wrapper = ({ children }: { children: ReactNode }) => ( | ||
<IntlProvider>{children}</IntlProvider> | ||
) | ||
|
||
// Creates a stubbed out router. We are just testing whether the navigation gets passed the correct route (aka "/tab1" or "/tab2") so we do not need the actual router and can just intecept the navgiation state. | ||
const mapRoute = createRoute({ | ||
getParentRoute: () => rootRoute, | ||
id: 'map', | ||
component: MapLayout, | ||
}) | ||
|
||
const catchAllRoute = createRoute({ | ||
getParentRoute: () => mapRoute, | ||
path: '$', | ||
component: () => null, | ||
}) | ||
|
||
const routeTree = rootRoute.addChildren([mapRoute.addChildren([catchAllRoute])]) | ||
|
||
const router = createRouter({ routeTree }) | ||
|
||
test('clicking tabs navigate to correct tab', () => { | ||
// @ts-expect-error - typings | ||
render(<RouterProvider router={router} />, { wrapper: Wrapper }) | ||
const settingsButton = screen.getByText('Settings') | ||
settingsButton.click() | ||
const settingsRouteName = router.state.location.pathname | ||
expect(settingsRouteName).toStrictEqual('/tab2') | ||
|
||
const observationTab = screen.getByTestId('tab-observation') | ||
observationTab.click() | ||
const observationTabRouteName = router.state.location.pathname | ||
expect(observationTabRouteName).toStrictEqual('/tab1') | ||
|
||
const aboutTab = screen.getByText('About') | ||
aboutTab.click() | ||
const aboutTabRoute = router.state.location.pathname | ||
expect(aboutTabRoute).toStrictEqual('/tab2') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,42 @@ | ||
import * as React from 'react' | ||
import { Paper } from '@mui/material' | ||
import Tab from '@mui/material/Tab' | ||
import Tabs from '@mui/material/Tabs' | ||
import { Outlet, createFileRoute, useNavigate } from '@tanstack/react-router' | ||
import { Suspense } from 'react' | ||
import { CircularProgress, Paper } from '@mui/material' | ||
import { styled } from '@mui/material/styles' | ||
import { Outlet, createFileRoute } from '@tanstack/react-router' | ||
|
||
import type { FileRoutesById } from '../../routeTree.gen' | ||
import { VERY_LIGHT_GREY, WHITE } from '../../colors' | ||
import { Tabs } from '../../components/Tabs' | ||
|
||
const Container = styled('div')({ | ||
display: 'flex', | ||
backgroundColor: WHITE, | ||
height: '100%', | ||
}) | ||
|
||
export const Route = createFileRoute('/(MapTabs)/_Map')({ | ||
component: MapLayout, | ||
}) | ||
|
||
export function MapLayout() { | ||
const navigate = useNavigate() | ||
const renderCount = React.useRef(0) | ||
renderCount.current = renderCount.current + 1 | ||
return ( | ||
<div> | ||
<Tabs | ||
onChange={(_, value) => navigate({ to: value as MapTabRoute })} | ||
orientation="vertical" | ||
> | ||
<MapTab label="Tab 1" value={'/tab1'} /> | ||
<MapTab label="Tab 2" value={'/tab2'} /> | ||
</Tabs> | ||
<Paper> | ||
<Outlet /> | ||
<Container> | ||
<Paper elevation={3} sx={{ display: 'flex' }}> | ||
<Tabs /> | ||
<div | ||
style={{ | ||
width: 300, | ||
borderLeftColor: VERY_LIGHT_GREY, | ||
borderLeftWidth: '1px', | ||
borderLeftStyle: 'solid', | ||
}} | ||
> | ||
<Suspense fallback={<CircularProgress />}> | ||
<Outlet /> | ||
</Suspense> | ||
</div> | ||
</Paper> | ||
<div>map component here</div> | ||
<div>parent map component render count: {renderCount.current}</div> | ||
</div> | ||
<Suspense fallback={<CircularProgress />}> | ||
<div>map component here</div> | ||
</Suspense> | ||
</Container> | ||
) | ||
} | ||
|
||
type TabProps = React.ComponentProps<typeof Tab> | ||
|
||
type MapTabRoute = { | ||
[K in keyof FileRoutesById]: K extends `${'/(MapTabs)/_Map'}${infer Rest}` | ||
? Rest extends '' | ||
? never | ||
: `${Rest}` | ||
: never | ||
}[keyof FileRoutesById] | ||
|
||
type MapTabProps = Omit<TabProps, 'value'> & { value: MapTabRoute } | ||
|
||
function MapTab(props: MapTabProps) { | ||
return <Tab {...props} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.