View changelog with demos on mantine.dev website
@mantine/emotion package
New @mantine/emotion package is now available to simplify migration
from 6.x to 7.x. 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 and updated 6.x to 7.x migration guide.
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.
use-field hook
New use-field hook is now available in @mantine/form
package.
It can be used as a simpler alternative to 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.
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:
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 by specifying them
in the mixins
option. To learn about mixins syntax, follow postcss-mixins documentation.
Note that this feature is available in postcss-preset-mantine
starting from version 1.15.0.
Example of adding clearfix
and circle
mixins:
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:
.demo {
@mixin clearfix;
@mixin circle 100px;
}
use-matches hook
New use-matches
hook exported from @mantine/core
is an alternative to 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 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 bered.9
- Between
theme.breakpoints.sm
andtheme.breakpoints.lg
, color will beorange.9
- Below
theme.breakpoints.sm
, color will beblue.9
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 now supports withBarValueLabel
prop that allows
displaying value label on top of each bar:
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 guide
- 6.x -> 7.x guide has been updated to include migration to @mantine/emotion package
- use-field hook documentation
- Uncontrolled form mode examples now include usage of
form.key()
function - Custom PostCSS mixins documentation
- use-matches hook documentation has been added to the responsive guide
Other changes
- Advanced templates now include GitHub workflows to run tests on CI
- AspectRatio component has been migrated to aspect-ratio CSS property