Version 3.2.0

Breaking changes

  • Group component was migrated to flexbox gap, it no longer uses hack with negative margins, thus withGutter prop is not longer supported.
  • Button component no longer supports link variant due to Styles API limitations, use Anchor component instead.
  • @mantine/core package no longer exports getFontStyles, getFocusStyles and hexToRgba functions, replace them with theme functions: theme.fn.fontStyles(), theme.fn.focusStyles(), theme.fn.rgba().
  • AppShell component was migrated to mobile-first approach, the way Navbar width is set was changed
  • use-idle hook options were changed to support initial state

Normalize.css and global styles on MantineProvider

MantineProvider now supports adding global styles and normalize.css with props:

<MantineProvider withGlobalStyles withNormalizeCSS>
<App />
</MantineProvider>

Functions on theme

Mantine theme now adds several functions (full list) that can help you write styles in createStyles function, styles and sx props:

import { createStyles } from '@mantine/core';
const useStyles = createStyles((theme) => ({
myResponsiveText: {
fontSize: theme.fontSizes.md,
[theme.fn.smallerThan('sm')]: {
fontSize: theme.fontSizes.sm,
},
[theme.fn.smallerThan(500)]: {
fontSize: theme.fontSizes.xs,
},
},
}));
function MyResponsiveText() {
const { classes } = useStyles();
return <div className={classes.myResponsiveText}>My responsive text</div>;
}

Custom properties on theme

You can now add any amount of custom properties on Mantine theme using other key:

// Add any other properties on theme
<MantineProvider
theme={{
other: {
fontFamilySecondary: 'Arial',
lineHeights: [1.2, 1.4, 1.6, 1.8, 1.95],
reduceMotion: true,
},
}}
>
<App />
</MantineProvider>
// Then use your custom properties
<Box sx={(theme) => ({
fontFamily: theme.other.fontFamilySecondary,
lineHeight: theme.other.lineHeight[2],
transitionDuration: theme.other.reduceMotion ? '0ms' : '200ms',
})} />

Mobile first approach

All layout components now support mobile first approach:

  • SimpleGrid component now supports minWidth breakpoints (cols prop is no longer required):
<SimpleGrid
breakpoints={[
{ minWidth: 'sm', cols: 2 },
{ minWidth: 'md', cols: 3 },
{ minWidth: 1200, cols: 4 },
]}
>
<div>1</div>
<div>2</div>
<div>3</div>
</SimpleGrid>
  • AppShell component was migrated to use mobile first approach (breaking change) – you will need to change how Navbar width is set:
// old way
<Navbar width={{ base: 400, breakpoints: { sm: '100%', lg: 500 } }} />
// new way (mobile first), base width defaults to 100%
<Navbar width={{ sm: 400, lg: 500 }} />

New @mantine/modals package

New @mantine/modals package is similar to @mantine/notification but for modals. It includes modals manager that allows you to:

  • create shared modals context storage
  • show confirm modals
  • handle multiple modals layers
import { Button, Text } from '@mantine/core';
import { openConfirmModal } from '@mantine/modals';
function Demo() {
const openDeleteModal = () =>
openConfirmModal({
title: 'Delete your profile',
centered: true,
children: (
<Text size="sm">
Are you sure you want to delete your profile? This action is destructive and you will have
to contact support to restore your data.
</Text>
),
labels: { confirm: 'Delete account', cancel: "No don't delete it" },
confirmProps: { color: 'red' },
onCancel: () => console.log('Cancel'),
onConfirm: () => console.log('Confirmed'),
});
return <Button onClick={openDeleteModal} color="red">Delete account</Button>;
}

New components and hooks

New Stepper component:

Step 2 content: Verify email
import { useState } from 'react';
import { Stepper, Button, Group } from '@mantine/core';
function Demo() {
const [active, setActive] = useState(1);
const nextStep = () => setActive((current) => (current < 3 ? current + 1 : current));
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current));
return (
<>
<Stepper active={active} onStepClick={setActive} breakpoint="sm">
<Stepper.Step label="First step" description="Create an account">
Step 1 content: Create an account
</Stepper.Step>
<Stepper.Step label="Second step" description="Verify email">
Step 2 content: Verify email
</Stepper.Step>
<Stepper.Step label="Final step" description="Get full access">
Step 3 content: Get full access
</Stepper.Step>
<Stepper.Completed>
Completed, click back button to get to previous step
</Stepper.Completed>
</Stepper>
<Group position="center" mt="xl">
<Button variant="default" onClick={prevStep}>Back</Button>
<Button onClick={nextStep}>Next step</Button>
</Group>
</>
);
}

New TransferList component:

Frameworks
Libraries
import { useState } from 'react';
import { TransferList, TransferListData } from '@mantine/core';
const initialValues: TransferListData = [
[
{ value: 'react', label: 'React' },
{ value: 'ng', label: 'Angular' },
{ value: 'next', label: 'Next.js' },
{ value: 'blitz', label: 'Blitz.js' },
{ value: 'gatsby', label: 'Gatsby.js' },
{ value: 'vue', label: 'Vue' },
{ value: 'jq', label: 'jQuery' },
],
[
{ value: 'sv', label: 'Svelte' },
{ value: 'rw', label: 'Redwood' },
{ value: 'np', label: 'NumPy' },
{ value: 'dj', label: 'Django' },
{ value: 'fl', label: 'Flask' },
],
];
function Demo() {
const [data, setData] = useState<TransferListData>(initialValues);
return (
<TransferList
value={data}
onChange={setData}
searchPlaceholder="Search..."
nothingFound="Nothing here"
titles={['Frameworks', 'Libraries']}
breakpoint="sm"
/>
);
}

With new use-os hook you can detect user os:

Your os is undetermined
import { useOs } from '@mantine/hooks';
function Demo() {
const os = useOs();
return <>Your os is <b>{os}</b></>;
}

New use-set-state lets you work with state like in class components:

const [state, setState] = useSetState({ name: 'John', age: 35, job: 'Engineer' });
state; // -> { name: 'John', age: 35, job: 'Engineer' }
setState({ name: 'Jane' }); // -> { name: 'Jane', age: 35, job: 'Engineer' }
setState({ age: 25, job: 'Manager' }); // -> { name: 'Jane', age: 25, job: 'Manager' }
setState((current) => ({ age: current.age + 7 })); // -> { name: 'Jane', age: 32, job: 'Manager' }

New features

DatePicker component now supports free input:

import { DatePicker } from '@mantine/dates';
function Demo() {
return <DatePicker allowFreeInput placeholder="Pick date" label="Event date" withAsterisk />;
}

DatePicker, DateRangePicker, Calendar and RangeCalendar components now support multiple months rendering:

import { DateRangePicker } from '@mantine/dates';
function Demo() {
return (
<>
<DateRangePicker amountOfMonths={2} label="2 months" />
<DateRangePicker amountOfMonths={3} label="3 months" />
</>
);
}

MultiSelect component now supports limiting maximum selected values:

import { MultiSelect } from '@mantine/core';
function Demo() {
return <MultiSelect maxSelectedValues={3} />;
}

PasswordInput component now supports visibility toggle icon changing:

import { PasswordInput } from '@mantine/core';
import { IconEyeCheck, IconEyeOff } from '@tabler/icons';
function Demo() {
return (
<PasswordInput
label="Change visibility toggle icon"
placeholder="Change visibility toggle icon"
defaultValue="secret"
visibilityToggleIcon={({ reveal, size }) =>
reveal ? <IconEyeOff size={size} /> : <IconEyeCheck size={size} />
}
/>
);
}

Other changes

  • 3 new guides were added: RTL Support, sx prop and Responsive styles
  • All date picking components from @mantine/dates package now support first day of week customization (either sunday or monday)
  • Tabs component pills variant was redesigned to be more neutral
  • Button and ActionIcon component now have hover effects
  • SegmentedControl component is now a generic – it accepts values as single type argument
  • Autocomplete, Select and MultiSelect dropdowns are now rendered with popper.js. This means that dropdown element is now aware of its position on screen and will change placement based on container scroll position. You should also experience less issues with z-index configuration.
  • Col component now supports responsive offset props: offsetXs={5}, offsetMd={10}, etc.
  • NumberInput component now supports empty value
  • You can now set default date format on MantineProvider, it will be used to format DatePicker and DateRangePicker inputs values
  • Checkbox component now supports default icons replacement
  • use-list-state hook now supports pop and shift handlers
  • use-idle hook now supports setting initial state
  • use-merged-ref hook now exports mergeRefs function, it supports refs merging for dynamic lists
  • use-focus-return hook now includes an option to disable automatic focus return and returns a function that can be used to return focus
  • use-move hook now supports onScrubStart and onScrubEnd callbacks