7.9.0
mantinedev/mantine7.9.0May 2, 2024by rtivital
AI Summary
Major release introducing the `@mantine/emotion` package for easier v6 to v7 migration, React 18.3 support, and new hooks like `use-field` and `use-matches`.
Key Highlights
- New `@mantine/emotion` package for simplified migration from v6
- Updated all components to support React 18.3
- New `use-field` hook for simpler single-field state management
- New `use-matches` hook for matching multiple media queries
- BarChart now supports `withBarValueLabel` prop
New Features
- @mantine/emotion package
- use-field hook
- use-matches hook
- withBarValueLabel prop
- Custom PostCSS mixins support
Full Release Notes
[View changelog with demos on mantine.dev website](https://mantine.dev/changelog/7-9-0)
## @mantine/emotion package
New [@mantine/emotion](https://mantine.dev/styles/emotion) package is now available to simplify migration
from [6.x to 7.x](https://mantine.dev/guides/6x-to-7x/). It includes `createStyles` function and additional
functionality for `sx` and `styles` props for all components similar to what was available
in `@mantine/core` package in v6.
If you still haven't migrated to 7.x because of the change in styling approach, you can now
have a smoother transition by using `@mantine/emotion` package. To learn more about the package,
visit the [documentation page](https://mantine.dev/styles/emotion) and updated [6.x to 7.x migration guide](https://mantine.dev/guides/6x-to-7x/).
```tsx
import { rem } from '@mantine/core';
import { createStyles } from '@mantine/emotion';
const useStyles = createStyles((theme, _, u) => ({
wrapper: {
maxWidth: rem(400),
width: '100%',
height: rem(180),
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginLeft: 'auto',
marginRight: 'auto',
borderRadius: theme.radius.sm,
// Use light and dark selectors to change styles based on color scheme
[u.light]: {
backgroundColor: theme.colors.gray[1],
},
[u.dark]: {
backgroundColor: theme.colors.dark[5],
},
// Reference theme.breakpoints in smallerThan and largerThan functions
[u.smallerThan('sm')]: {
// Child reference in nested selectors via ref
[`& .${u.ref('child')}`]: {
fontSize: theme.fontSizes.xs,
},
},
},
child: {
// Assign selector to a ref to reference it in other styles
ref: u.ref('child'),
padding: theme.spacing.md,
borderRadius: theme.radius.sm,
boxShadow: theme.shadows.md,
[u.light]: {
backgroundColor: theme.white,
color: theme.black,
},
[u.dark]: {
backgroundColor: theme.colors.dark[8],
color: theme.white,
},
},
}));
function Demo() {
const { classes } = useStyles();
return (
<div className={classes.wrapper}>
<div className={classes.child}>createStyles demo</div>
</div>
);
}
```
## React 18.3 support
All `@mantine/*` components and hooks have been updated to support React 18.3. It is
recommended to update your application as well to prepare for the upcoming [React 19 release](https://react.dev/blog/2024/04/25/react-19).
## use-field hook
New [use-field](https://mantine.dev/form/use-field) hook is now available in `@mantine/form` package.
It can be used as a simpler alternative to [use-form](https://mantine.dev/form/use-form) hook to manage state of a single input without the need to create a form.
The hook supports most of `use-form` hook features: validation with function, touched and
dirty state, error message, validation on change/blur and more.
```tsx
import { TextInput } from '@mantine/core';
import { isEmail, useField } from '@mantine/form';
function Demo() {
const field = useField({
initialValue: '',
validateOnChange: true,
validate: isEmail('Invalid email'),
});
return <TextInput {...field.getInputProps()} label="Email" placeholder="Enter your email" />;
}
```
`use-field` hook also supports async validation:
```tsx
import { Button, Loader, TextInput } from '@mantine/core';
import { useField } from '@mantine/form';
function validateAsync(value: string): Promise<string | null> {
return new Promise((resolve) => {
window.setTimeout(() => {
resolve(value === 'mantine' ? null : 'Value must be "mantine"');
}, 800);
});
}
function Demo() {
const field = useField({
initialValue: '',
validate: validateAsync,
});
return (
<>
<TextInput
{...field.getInputProps()}
label="Enter 'mantine'"
placeholder="Enter 'mantine'"
rightSection={field.isValidating ? <Loader size={18} /> : null}
mb="md"
/>
<Button onClick={field.validate}>Validate async</Button>
</>
);
}
```
## Custom PostCSS mixins
You can now define custom mixins that are not included in [mantine-postcss-preset](https://mantine.dev/styles/postcss-preset) by specifying them
in the `mixins` option. To learn about mixins syntax, follow [postcss-mixins documentation](https://github.com/postcss/postcss-mixins#readme).
Note that this feature is available in `postcss-preset-mantine` starting from version 1.15.0.
Example of adding `clearfix` and `circle` mixins:
```tsx
module.exports = {
plugins: {
'postcss-preset-mantine': {
autoRem: true,
mixins: {
clearfix: {
'&::after': {
content: '""',
display: 'table',
clear: 'both',
},
},
circle: (_mixin, size) => ({
borderRadius: '50%',
width: size,
height: size,
}),
},
},
// ... Other plugins
},
};
```
Then you can use these mixins in your styles:
```scss
.demo {
@mixin clearfix;
@mixin circle 100px;
}
```
## use-matches hook
New `use-matches` hook exported from `@mantine/core` is an alternative to [use-media-query](https://mantine.dev/hooks/use-media-query/)
if you need to match multiple media queries and values. It accepts an object with media queries as keys and
values at given breakpoint as values.
Note that `use-matches` hook uses the same logic as [use-media-query](https://mantine.dev/hooks/use-media-query/) under the hood,
it is not recommended to be used as a primary source of responsive styles, especially if you have ssr in your application.
In the following example:
- Starting from `theme.breakpoints.lg`, color will be `red.9`
- Between `theme.breakpoints.sm` and `theme.breakpoints.lg`, color will be `orange.9`
- Below `theme.breakpoints.sm`, color will be `blue.9`
```tsx
import { Box, useMatches } from '@mantine/core';
function Demo() {
const color = useMatches({
base: 'blue.9',
sm: 'orange.9',
lg: 'red.9',
});
return (
<Box bg={color} c="white" p="xl">
Box with color that changes based on screen size
</Box>
);
}
```
## BarChart value label
[BarChart](https://mantine.dev/charts/bar-chart) now supports `withBarValueLabel` prop that allows
displaying value label on top of each bar:
```tsx
import { BarChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<BarChart
h={300}
data={data}
dataKey="month"
valueFormatter={(value) => new Intl.NumberFormat('en-US').format(value)}
withBarValueLabel
series={[
{ name: 'Smartphones', color: 'violet.6' },
{ name: 'Laptops', color: 'blue.6' },
{ name: 'Tablets', color: 'teal.6' },
]}
/>
);
}
```
## Documentation updates
- New [usage with emotion](https://mantine.dev/styles/emotion) guide
- [6.x -> 7.x](https://mantine.dev//guides/6x-to-7x/) guide has been updated to include migration to [@mantine/emotion](https://mantine.dev/styles/emotion) package
- [use-field](https://mantine.dev/form/use-field) hook documentation
- [Uncontrolled form mode](https://mantine.dev/form/uncontrolled) examples now include usage of `form.key()` function
- [Custom PostCSS mixins](https://mantine.dev/styles/postcss-preset/#custom-mixins) documentation
- [use-matches](https://mantine.dev/styles/responsive/#use-matches-hook) hook documentation has been added to the responsive guide
## Other changes
- Advanced templates now include GitHub workflows to run tests on CI
- [AspectRatio](https://mantine.dev/core/aspect-ratio) component has been migrated to [aspect-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) CSS property