Update template to 7.0
* Update template to v7 alpha * Add storybook * Update readme * Fix inaccurate welcome message description * Update @mantine/* dependencies to version 1.6.0 * Update @mantine/* dependencies to version 7.0.0-beta.2 * Update @mantine/* dependencies to version 7.0.0-beta.5 * Update meta tags * Update @mantine/* dependencies to version 7.0.0-beta.7 * Update @mantine/* dependencies to version 7.0.0
This commit is contained in:
parent
8434507580
commit
2acb87787a
|
|
@ -0,0 +1,12 @@
|
|||
import type { StorybookConfig } from '@storybook/react-vite';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../src/**/*.mdx', '../src/**/*.story.@(js|jsx|ts|tsx)'],
|
||||
addons: ['@storybook/addon-essentials', '@storybook/addon-styling', 'storybook-dark-mode'],
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import '@mantine/core/styles.css';
|
||||
import React, { useEffect } from 'react';
|
||||
import { addons } from '@storybook/preview-api';
|
||||
import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
|
||||
import { MantineProvider, useMantineColorScheme } from '@mantine/core';
|
||||
import { theme } from '../src/theme';
|
||||
|
||||
const channel = addons.getChannel();
|
||||
|
||||
function ColorSchemeWrapper({ children }: { children: React.ReactNode }) {
|
||||
const { setColorScheme } = useMantineColorScheme();
|
||||
const handleColorScheme = (value: boolean) => setColorScheme(value ? 'dark' : 'light');
|
||||
|
||||
useEffect(() => {
|
||||
channel.on(DARK_MODE_EVENT_NAME, handleColorScheme);
|
||||
return () => channel.off(DARK_MODE_EVENT_NAME, handleColorScheme);
|
||||
}, [channel]);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
export const decorators = [
|
||||
(renderStory: any) => <ColorSchemeWrapper>{renderStory()}</ColorSchemeWrapper>,
|
||||
(renderStory: any) => <MantineProvider theme={theme}>{renderStory()}</MantineProvider>,
|
||||
];
|
||||
36
README.md
36
README.md
|
|
@ -1,8 +1,34 @@
|
|||
# Mantine + Vite template
|
||||
# Mantine Vite template
|
||||
|
||||
Official [Mantine](https://mantine.dev/) + [Vite](https://vitejs.dev/) template.
|
||||
## Features
|
||||
|
||||
Links:
|
||||
This template comes with the following features:
|
||||
|
||||
- [Mantine documentation](https://mantine.dev/)
|
||||
- [Vite documentation](https://vitejs.dev/)
|
||||
- [PostCSS](https://postcss.org/) with [mantine-postcss-preset](https://mantine.dev/styles/postcss-preset)
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- [Storybook](https://storybook.js.org/)
|
||||
- [Jest](https://jestjs.io/) setup with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro)
|
||||
- ESLint setup with [eslint-config-mantine](https://github.com/mantinedev/eslint-config-mantine)
|
||||
|
||||
## npm scripts
|
||||
|
||||
## Build and dev scripts
|
||||
|
||||
- `dev` – start development server
|
||||
- `build` – build production version of the app
|
||||
- `preview` – locally preview production build
|
||||
|
||||
### Testing scripts
|
||||
|
||||
- `typecheck` – checks TypeScript types
|
||||
- `lint` – runs ESLint
|
||||
- `prettier:check` – checks files with Prettier
|
||||
- `jest` – runs jest tests
|
||||
- `jest:watch` – starts jest watch
|
||||
- `test` – runs `jest`, `prettier:check`, `lint` and `typecheck` scripts
|
||||
|
||||
### Other scripts
|
||||
|
||||
- `storybook` – starts storybook dev server
|
||||
- `storybook:build` – build production storybook bundle to `storybook-static`
|
||||
- `prettier:write` – formats all files with Prettier
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
|
||||
/>
|
||||
<title>Vite + Mantine App</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
||||
moduleNameMapper: {
|
||||
'^@test-utils': '<rootDir>/test-utils',
|
||||
'\\.css$': 'identity-obj-proxy',
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
|
|
|
|||
57
package.json
57
package.json
|
|
@ -12,27 +12,37 @@
|
|||
"prettier:write": "prettier --write \"**/*.{ts,tsx}\"",
|
||||
"jest": "jest",
|
||||
"jest:watch": "jest --watch",
|
||||
"test": "npm run typecheck && npm run prettier && npm run lint && npm run jest && npm run build"
|
||||
"test": "npm run typecheck && npm run prettier && npm run lint && npm run jest && npm run build",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"storybook:build": "storybook build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@mantine/core": "6.0.0",
|
||||
"@mantine/hooks": "6.0.0",
|
||||
"@mantine/core": "7.0.0",
|
||||
"@mantine/hooks": "7.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "^8.20.0",
|
||||
"@storybook/addon-essentials": "^7.0.18",
|
||||
"@storybook/addon-interactions": "^7.0.18",
|
||||
"@storybook/addon-links": "^7.0.18",
|
||||
"@storybook/addon-styling": "^1.0.8",
|
||||
"@storybook/blocks": "^7.0.18",
|
||||
"@storybook/react": "^7.0.18",
|
||||
"@storybook/react-vite": "^7.0.18",
|
||||
"@storybook/testing-library": "^0.0.14-next.2",
|
||||
"@testing-library/dom": "^9.3.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"eslint": "^8.33.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/react": "^18.2.7",
|
||||
"@types/react-dom": "^18.2.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
||||
"@typescript-eslint/parser": "^5.59.7",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-mantine": "2.0.0",
|
||||
|
|
@ -40,11 +50,18 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"jest": "^29.4.1",
|
||||
"jest-environment-jsdom": "^29.4.1",
|
||||
"prettier": "^2.8.3",
|
||||
"ts-jest": "^29.0.5",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.1.1"
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-preset-mantine": "1.6.0",
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prop-types": "^15.8.1",
|
||||
"storybook": "^7.0.18",
|
||||
"storybook-dark-mode": "^3.0.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.9"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-preset-mantine': {},
|
||||
'postcss-simple-vars': {
|
||||
variables: {
|
||||
'mantine-breakpoint-xs': '36em',
|
||||
'mantine-breakpoint-sm': '48em',
|
||||
'mantine-breakpoint-md': '62em',
|
||||
'mantine-breakpoint-lg': '75em',
|
||||
'mantine-breakpoint-xl': '88em',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
12
src/App.tsx
12
src/App.tsx
|
|
@ -1,10 +1,12 @@
|
|||
import { ThemeProvider } from './ThemeProvider';
|
||||
import { Welcome } from './Welcome/Welcome';
|
||||
import '@mantine/core/styles.css';
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import { Router } from './Router';
|
||||
import { theme } from './theme';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<ThemeProvider>
|
||||
<Welcome />
|
||||
</ThemeProvider>
|
||||
<MantineProvider theme={theme}>
|
||||
<Router />
|
||||
</MantineProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||
import { HomePage } from './pages/Home.page';
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: <HomePage />,
|
||||
},
|
||||
]);
|
||||
|
||||
export function Router() {
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import { MantineProvider, MantineThemeOverride } from '@mantine/core';
|
||||
|
||||
export const theme: MantineThemeOverride = {
|
||||
colorScheme: 'dark',
|
||||
};
|
||||
|
||||
interface ThemeProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function ThemeProvider({ children }: ThemeProviderProps) {
|
||||
return (
|
||||
<MantineProvider withGlobalStyles withNormalizeCSS theme={theme}>
|
||||
{children}
|
||||
</MantineProvider>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import { screen } from '@testing-library/react';
|
||||
import { render } from '@test-utils';
|
||||
import { Welcome } from './Welcome';
|
||||
|
||||
it('displays welcome text', () => {
|
||||
render(<Welcome />);
|
||||
expect(screen.getByText('Welcome to Mantine!')).toBeInTheDocument();
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { Button, Stack, Text } from '@mantine/core';
|
||||
|
||||
export function Welcome() {
|
||||
return (
|
||||
<Stack align="center" mt={50}>
|
||||
<Text size="xl" weight={500}>
|
||||
Welcome to Mantine!
|
||||
</Text>
|
||||
<Button>Click the button</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { Button, Group, useMantineColorScheme } from '@mantine/core';
|
||||
|
||||
export function ColorSchemeToggle() {
|
||||
const { setColorScheme } = useMantineColorScheme();
|
||||
|
||||
return (
|
||||
<Group justify="center" mt="xl">
|
||||
<Button onClick={() => setColorScheme('light')}>Light</Button>
|
||||
<Button onClick={() => setColorScheme('dark')}>Dark</Button>
|
||||
<Button onClick={() => setColorScheme('auto')}>Auto</Button>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.title {
|
||||
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||
font-size: rem(100px);
|
||||
font-weight: 900;
|
||||
letter-spacing: rem(-2px);
|
||||
|
||||
@media (max-width: $mantine-breakpoint-md) {
|
||||
font-size: rem(50px);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { Welcome } from './Welcome';
|
||||
|
||||
export default {
|
||||
title: 'Welcome',
|
||||
};
|
||||
|
||||
export const Usage = () => <Welcome />;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { render, screen } from '@test-utils';
|
||||
import { Welcome } from './Welcome';
|
||||
|
||||
describe('Welcome component', () => {
|
||||
it('has correct Vite guide link', () => {
|
||||
render(<Welcome />);
|
||||
expect(screen.getByText('this guide')).toHaveAttribute(
|
||||
'href',
|
||||
'https://mantine.dev/guides/vite/'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { Title, Text, Anchor } from '@mantine/core';
|
||||
import classes from './Welcome.module.css';
|
||||
|
||||
export function Welcome() {
|
||||
return (
|
||||
<>
|
||||
<Title className={classes.title} ta="center" mt={100}>
|
||||
Welcome to{' '}
|
||||
<Text inherit variant="gradient" component="span" gradient={{ from: 'pink', to: 'yellow' }}>
|
||||
Mantine
|
||||
</Text>
|
||||
</Title>
|
||||
<Text color="dimmed" ta="center" size="lg" maw={580} mx="auto" mt="xl">
|
||||
This starter Vite project includes a minimal setup, if you want to learn more on Mantine +
|
||||
Vite integration follow{' '}
|
||||
<Anchor href="https://mantine.dev/guides/vite/" size="lg">
|
||||
this guide
|
||||
</Anchor>
|
||||
. To get started edit pages/Home.page.tsx file.
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { Welcome } from '../components/Welcome/Welcome';
|
||||
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
|
||||
|
||||
export function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<Welcome />
|
||||
<ColorSchemeToggle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { createTheme } from '@mantine/core';
|
||||
|
||||
export const theme = createTheme({
|
||||
/** Put your mantine theme override here */
|
||||
});
|
||||
|
|
@ -1 +1,5 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
export * from '@testing-library/react';
|
||||
export { render } from './render';
|
||||
export { userEvent };
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { render as testingLibraryRender } from '@testing-library/react';
|
||||
import { ThemeProvider } from '../src/ThemeProvider';
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import { theme } from '../src/theme';
|
||||
|
||||
export function render(children: React.ReactNode) {
|
||||
const { rerender, ...others } = testingLibraryRender(<ThemeProvider>{children}</ThemeProvider>);
|
||||
return {
|
||||
rerender: (ui: React.ReactElement<any, string | React.JSXElementConstructor<any>>) =>
|
||||
rerender(<ThemeProvider>{ui}</ThemeProvider>),
|
||||
...others,
|
||||
};
|
||||
export function render(ui: React.ReactNode) {
|
||||
return testingLibraryRender(<>{ui}</>, {
|
||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||
<MantineProvider theme={theme}>{children}</MantineProvider>
|
||||
),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@test-utils": ["./test-utils"]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue