Styled components support

You can now use styled components syntax with @emotion/styled package:

  • It is fully compatible with Mantine server side rendering (@mantine/next, @mantine/remix and gatsby-plugin-mantine packages)
  • Mantine theme can now be used in component styles with no extra setup
  • Components created with @emotion/styled will use Mantine's emotion cache
Styled component
import styled from '@emotion/styled';
const StyledComponent = styled.div`
text-align: center;
background-color: ${({ theme }) =>
theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0]};
padding: 30px;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: ${({ theme }) =>
theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1]};
}
`;
function Demo() {
return <StyledComponent />;
}

withAsterisk prop

All inputs that are based on Input and Input.Wrapper components now support withAsterisk prop, it allows to display required asterisk without adding required attribute to the input element. It is useful when you do not need browser validation in your forms but still want to display the asterisk.

import { TextInput } from '@mantine/core';
// Will display required asterisk and add `required` attribute to the input element
function RequiredDemo() {
return <TextInput label="test-label" required />;
}
// Will only display the asterisk, `required` attribute is not added to the input element
function AsteriskDemo() {
return <TextInput label="test-label" withAsterisk />;
}

Progress and RingProgress tooltips

Progress and RingProgress components now support floating tooltips in sections:

Hover sections to see tooltips
import { RingProgress, Text, Group } from '@mantine/core';
function Demo() {
return (
<Group position="center">
<RingProgress
size={170}
thickness={16}
label={
<Text size="xs" align="center" px="xs" sx={{ pointerEvents: 'none' }}>
Hover sections to see tooltips
</Text>
}
sections={[
{ value: 40, color: 'cyan', tooltip: 'Documents – 40 Gb' },
{ value: 25, color: 'orange', tooltip: 'Apps – 25 Gb' },
{ value: 15, color: 'grape', tooltip: 'Other – 15 Gb' },
]}
/>
</Group>
);
}
Documents
Apps
Other
import { Progress } from '@mantine/core';
function Demo() {
return (
<Progress
radius="xl"
size={24}
sections={[
{ value: 33, color: 'pink', label: 'Documents', tooltip: 'Document – 33 Gb' },
{ value: 28, color: 'grape', label: 'Apps', tooltip: 'Apps – 28 Gb' },
{ value: 25, color: 'violet', label: 'Other', tooltip: 'Other – 25 Gb' },
]}
/>
);
}

Title component changes

Title now supports setting size different from order:

H3 heading with h1 font-size

H1 heading with h4 font-size

H1 heading with 12px size

import { Title } from '@mantine/core';
function Demo() {
return (
<>
<Title order={3} size="h1">
H3 heading with h1 font-size
</Title>
<Title size="h4">H1 heading with h4 font-size</Title>
<Title size={12}>H1 heading with 12px size</Title>
</>
);
}

It also now supports all Text component props:

H3 heading aligned to center with 100 font-weight

Underlined h4 heading with blue color

Italic dimmed h5 heading
import { Title } from '@mantine/core';
function Demo() {
return (
<>
<Title order={3} weight={100} align="center">
H3 heading aligned to center with 100 font-weight
</Title>
<Title order={4} underline color="blue.5">
Underlined h4 heading with blue color
</Title>
<Title order={5} color="dimmed" italic>
Italic dimmed h5 heading
</Title>
</>
);
}

@mantine/form changes

New form.isValid handler performs form validation with given validation functions, rules object or schema, but unlike form.validate it does not set form.errors and just returns boolean value that indicates whether form is valid.

import { useForm } from '@mantine/form';
const form = useForm({
initialValues: { name: '', age: 0 },
validate: {
name: (value) => (value.trim().length < 2 ? 'Too short' : null),
age: (value) => (value < 18 ? 'Too young' : null),
},
});
// get validation status of all values
form.isValid(); // -> false
// get validation status of field
form.isValid('name'); // -> false

form.resetDirty will now memoize form values and compare all next changes with stored values instead of initialValues:

import { useForm } from '@mantine/form';
const form = useForm({ initialValues: { a: 1 } });
form.setFieldValue('a', 2);
form.isDirty(); // -> true
form.setFieldValue('a', 1);
form.isDirty(); // -> false
form.setFieldValue('a', 3);
form.resetDirty();
form.isDirty(); // -> false
form.setFieldValue('a', 3);
form.isDirty(); // -> true

Form rules now receive rule path as third argument:

import { useForm } from '@mantine/form';
const form = useForm({
initialValues: { a: [{ b: 1 }, { b: 2 }] },
validate: {
a: {
// path can be used to get field position relative to other fields
b: (value, values, path) => (path === 'a.0.b' ? 'error' : null),
},
},
});

Custom prism themes

Prism component now supports custom themes with getPrismTheme prop:

import { Button } from '@mantine/core';
function Demo() {
return <Button>Hello</Button>
}
import duotoneDark from 'prism-react-renderer/themes/duotoneDark';
import duotoneLight from 'prism-react-renderer/themes/duotoneLight';
import { Prism } from '@mantine/prism';
const demoCode = `import { Button } from '@mantine/core';
function Demo() {
return <Button>Hello</Button>
}`;
function Demo() {
return (
<Prism
language="tsx"
getPrismTheme={(_theme, colorScheme) =>
colorScheme === 'light' ? duotoneLight : duotoneDark
}
>
{demoCode}
</Prism>
);
}

Other changes

  • ActionIcon component now support gradient variant
  • Avatar component now supports variant prop
  • Carousel component now supports height="100%"
  • Grid.Col now supports order prop, it can be used to reorder columns when certain breakpoint is reached
  • Tabs component now supports keepMounted prop. If it is set to false then components rendered inside Tabs.Panel will be unmounted when tab is not active.
  • DatePicker and DateRangePicker components now have withinPortal prop set to false by default to match other components