Skip to content

Commit 98dc3c8

Browse files
committed
feat: setup mantine and implement ThemeProvider
1 parent 41e5d72 commit 98dc3c8

File tree

10 files changed

+348
-10
lines changed

10 files changed

+348
-10
lines changed

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@
3535
"dependencies": {
3636
"@lingui/core": "^5.1.2",
3737
"@lingui/react": "^5.1.2",
38+
"@mantine/core": "^7.15.2",
39+
"@mantine/dates": "^7.15.2",
40+
"@mantine/hooks": "^7.15.2",
41+
"@mantine/modals": "^7.15.2",
42+
"@mantine/notifications": "^7.15.2",
3843
"concurrently": "^9.1.0",
44+
"dayjs": "^1.11.13",
3945
"react": "^19.0.0",
4046
"react-dom": "^19.0.0",
4147
"zustand": "^5.0.2"
@@ -89,7 +95,10 @@
8995
"jest": "^29.7.0",
9096
"jest-environment-jsdom": "^29.7.0",
9197
"lint-staged": "^15.2.11",
98+
"postcss": "^8.4.49",
9299
"postcss-html": "^1.7.0",
100+
"postcss-preset-mantine": "^1.17.0",
101+
"postcss-simple-vars": "^7.0.1",
93102
"sass-embedded": "^1.83.0",
94103
"stylelint": "^16.12.0",
95104
"stylelint-config-hudochenkov": "^11.0.0",

postcss.config.cjs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
plugins: {
3+
'postcss-preset-mantine': {},
4+
'postcss-simple-vars': {
5+
variables: {
6+
'mantine-breakpoint-lg': '75em',
7+
'mantine-breakpoint-md': '62em',
8+
'mantine-breakpoint-sm': '48em',
9+
'mantine-breakpoint-xl': '88em',
10+
'mantine-breakpoint-xs': '36em',
11+
},
12+
},
13+
},
14+
};

src/main.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createRouter,RouterProvider } from '@tanstack/react-router';
22
import { StrictMode } from 'react';
33
import { createRoot } from 'react-dom/client';
44

5-
import { IntlProvider } from './providers';
5+
import { IntlProvider, ThemeProvider } from './providers';
66
import { routeTree } from './route-tree.gen';
77

88
const router = createRouter({
@@ -23,7 +23,9 @@ if (!rootElement.innerHTML) {
2323
root.render(
2424
<StrictMode>
2525
<IntlProvider locale="en">
26-
<RouterProvider router={router} />
26+
<ThemeProvider>
27+
<RouterProvider router={router} />
28+
</ThemeProvider>
2729
</IntlProvider>
2830
</StrictMode>,
2931
);

src/providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './intl';
2+
export * from './theme';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`ThemeProvider Component matches snapshot 1`] = `
4+
<DocumentFragment>
5+
<style
6+
data-mantine-styles="classes"
7+
>
8+
@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}
9+
</style>
10+
<div>
11+
Snapshot Content
12+
</div>
13+
</DocumentFragment>
14+
`;

src/providers/theme/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './theme.provider';
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { renderWrapper, screen } from '@/tests';
2+
3+
describe('ThemeProvider Component', () => {
4+
it('should render children', async () => {
5+
renderWrapper(
6+
<div>Children of Theme Provider</div>,
7+
);
8+
9+
expect(screen.getByText('Children of Theme Provider')).toBeInTheDocument();
10+
});
11+
12+
it('forwards props to MantineProvider', () => {
13+
const props = { theme: { defaultColorScheme: 'dark' } };
14+
15+
renderWrapper(
16+
<div>Children of Theme Provider</div>,
17+
{
18+
...props,
19+
},
20+
);
21+
22+
const htmlElement = document.documentElement;
23+
24+
expect(htmlElement).toHaveAttribute('data-mantine-color-scheme', 'dark');
25+
});
26+
27+
it('renders correctly without additional props', () => {
28+
const { container } = renderWrapper(
29+
<div>Default Content</div>,
30+
);
31+
32+
expect(container).toBeInTheDocument();
33+
});
34+
35+
it('matches snapshot', () => {
36+
const { asFragment } = renderWrapper(
37+
<div>Snapshot Content</div>,
38+
);
39+
40+
expect(asFragment()).toMatchSnapshot();
41+
});
42+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import '@mantine/core/styles.css';
2+
3+
import { MantineProvider } from '@mantine/core';
4+
import type { ComponentProps, PropsWithChildren } from 'react';
5+
6+
export const ThemeProvider = ({ children, ...props }: PropsWithChildren<ComponentProps<typeof MantineProvider>>) => {
7+
return (
8+
<MantineProvider {...props}>
9+
{children}
10+
</MantineProvider>
11+
);
12+
};

src/tests/utils/render.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { render as testingLibraryRender } from '@testing-library/react';
22

3-
import { IntlProvider } from '../../providers';
3+
import { IntlProvider, ThemeProvider } from '../../providers';
44

5-
export const renderWrapper = (ui: React.ReactNode, { locale = 'en' } = {}) => {
5+
export const renderWrapper = (ui: React.ReactNode, { locale = 'en', theme = {} } = {}) => {
66
return testingLibraryRender(
77
<IntlProvider locale={locale}>
8-
{ui}
8+
<ThemeProvider {...theme} >
9+
{ui}
10+
</ThemeProvider>
911
</IntlProvider>,
1012
);
1113
};

0 commit comments

Comments
 (0)