Version 3.0.0

Release date

Breaking changes

  • Mantine was migrated to emotion from react-jss and no longer supports react-jss
  • @mantine/core package no longer exports react-jss theming context, use createStyles instead
  • All components no longer support themeOverride prop due to performance reasons
  • elementRef prop was replaced with ref in all components
  • Default line-height (theme.lineHeight) was increased from 1.4 to 1.55
  • Default Container sizes were changed
  • Divider component no longer supports margins prop, use mx or my instead
  • createStyles function now returns an object of { classes, cx } instead of just classes

Migration to emotion

Mantine no longer uses react-jss, all components were migrated to emotion based css-in-js library exposed as separate @mantine/styles package and as a part of @mantine/core. This means that you will have to:

  • migrate all of your custom styles built with react-jss to new createStyles hook creator
  • setup new strategy for server side rendering

createStyles

Read createStyles documentation

From version 3.0 createStyles is the main way to add styles to Mantine components. Core features:

  • API is similar to react-jss
  • As fast and lightweight as emotion: createStyles extends @emotion/react
  • Subscribes to your Mantine theming context
  • Supports all emotion features: automatic critical css extraction during server side rendering, lazy evaluation, dynamic theming, etc.
  • Server side rendering support: Next.js, Gatsby or any other environment
  • Fully featured TypeScript support

Basic createStyles usage example:

createStyles demo
import { createStyles } from '@mantine/core';
const useStyles = createStyles((theme, _params, getRef) => ({
wrapper: {
// subscribe to color scheme changes right in your styles
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1],
maxWidth: 400,
width: '100%',
height: 180,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginLeft: 'auto',
marginRight: 'auto',
borderRadius: theme.radius.sm,
// Dynamic media queries, define breakpoints in theme, use anywhere
[`@media (max-width: ${theme.breakpoints.sm}px)`]: {
// Type safe child reference in nested selectors via ref
[`& .${getRef('child')}`]: {
fontSize: theme.fontSizes.xs,
},
},
},
child: {
// assign ref to element
ref: getRef('child'),
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.white,
padding: theme.spacing.md,
borderRadius: theme.radius.sm,
boxShadow: theme.shadows.md,
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
},
}));
function Demo() {
const { classes } = useStyles();
return (
<div className={classes.wrapper}>
<div className={classes.child}>createStyles demo</div>
</div>
);
}

Server side rendering

Since Mantine now uses emotion instead of react-jss you will need to change server side rendering strategy. Mantine now has 3 new packages to help you setup server side rendering:

  • @mantine/ssr – general server side rendering utilities
  • @mantine/next – Next.js specific ssr configurations
  • gatsby-plugin-mantine – enable ssr in Gatsby

Follow these guides to get started with ssr:

Ref forwarding

All components that previously used elementRef were rebuilt with React.forwardRef, use ref prop to access element ref:

<TextInput ref={(node) => {}} />

Unique ids during ssr

It's no longer required to set static ids on Grid, Menu, all inputs and some other components if you wrap your application in MantineProvider.

<TextInput /> // -> will render fine during ssr
<TextInput id="not-necessary" /> // -> id is no longer necessary

ColorSchemeProvider

ColorSchemeProvider is a new component that will help you manage color scheme (read full docs):

import { MantineProvider, ColorSchemeProvider, ColorScheme } from '@mantine/core';
export default function Demo() {
const [colorScheme, setColorScheme] = useState('light');
const toggleColorScheme = (value?: ColorScheme) =>
setColorScheme(value || (colorScheme === 'dark' ? 'light' : 'dark'));
return (
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}>
<MantineProvider theme={{ colorScheme }}>
<App />
</MantineProvider>
</ColorSchemeProvider>
);
}
// ...later in other component
import { ActionIcon, useMantineColorScheme } from '@mantine/core';
import { SunIcon, MoonIcon } from '@modulz/radix-icons';
function Demo() {
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
const dark = colorScheme === 'dark';
return (
<ActionIcon
variant="outline"
color={dark ? 'yellow' : 'blue'}
onClick={() => toggleColorScheme()}
title="Toggle color scheme"
>
{dark ? (
<SunIcon style={{ width: 18, height: 18 }} />
) : (
<MoonIcon style={{ width: 18, height: 18 }} />
)}
</ActionIcon>
);
}

Margin props

All components now support setting following props to control margins:

  • m – sets margin property on root element
  • my – sets margin-top and margin-bottom properties on root element
  • mx – sets margin-right and margin-left properties on root element
  • mt – sets margin-top property on root element
  • mb – sets margin-bottom property on root element
  • ml – sets margin-left property on root element
  • mr – sets margin-right property on root element
import { Button, TextInput } from '@mantine/core';
function Demo() {
return (
<div>
<Button mx={20}>My button</Button>
<TextInput mt="md" />
</div>
);
}

@mantine/dropzone package

@mantine/dropzone is a new package that includes Dropzone and FullScreenDropzone components.

Dropzone components lets you capture files from user with drag 'n' drop:

FullScreenDropzone works the same way as dropzone but instead of capturing dropped files from specific area it uses browser window as dropzone:

New components

MediaQuery component provides a simple API to manage breakpoints in jsx:

- larger than lg
- Smaller than lg
- Smaller than xl, larger than sm
- Smaller than 1500px, larger than 800px
import { useMantineTheme, MediaQuery, Stack, Box, CSSObject } from '@mantine/core';
function Demo() {
const theme = useMantineTheme();
const highlight: CSSObject = {
backgroundColor:
theme.colorScheme === 'dark'
? theme.fn.rgba(theme.colors.blue[7], 0.25)
: theme.colors.blue[0],
border: `1px solid ${
theme.colorScheme === 'dark' ? theme.colors.blue[6] : theme.colors.blue[3]
}`,
};
const boxStyles = {
borderRadius: 3,
padding: '3px 5px',
border: '1px solid transparent',
};
return (
<Stack spacing={5}>
<MediaQuery largerThan="lg" styles={highlight}>
<Box sx={boxStyles}>- larger than lg</Box>
</MediaQuery>
<MediaQuery smallerThan="lg" styles={highlight}>
<Box sx={boxStyles}>- Smaller than lg</Box>
</MediaQuery>
<MediaQuery smallerThan="xl" largerThan="sm" styles={highlight}>
<Box sx={boxStyles}>- Smaller than xl, larger than sm</Box>
</MediaQuery>
<MediaQuery smallerThan={1500} largerThan={800} styles={highlight}>
<Box sx={boxStyles}>- Smaller than 1500px, larger than 800px</Box>
</MediaQuery>
</Stack>
);
}

New features

Select and MultiSelect components now support creating new items, items grouping and disabling:

Accordion component now supports more options to customize icons and labels:

  • iconPosition prop let's you choose where chevron icon will be rendered: right or left
  • with icon prop on Accordion and Accordion.Item components you can replace icons of all items at once or of each item individually

Avatar component now supports stacking with AvatarsGroup:

+5

New hooks

use-resize-observer lets you subscribe to element size and position changes with ResizeObserver:

Resize textarea by dragging its right bottom corner
Rect: { "x": 0, "y": 0, "width": 0, "height": 0, "top": 0, "left": 0, "bottom": 0, "right": 0 }

use-viewport-size hook returns viewport width and height:

Width: 0, height: 0

use-mouse hook tracks mouse position over given element:

Mouse coordinates { x: 0, y: 0 }

use-hover hook detects if mouse is over given element:

Put mouse over me please

Other changes

  • ActionIcon and Button components now support new default variant
  • Pagination component now supports adding first and last controls and removing next/prev buttons
  • SimpleGrid component now supports theme.breakpoints usage in breakpoints prop
  • SimpleGrid was migrated to use CSS Grid Layout instead of flexbox
  • Group component no longer supports Styles API, you can add styles directly to element and children instead
  • New Space component lets you add spacing between elements without directly subscribing to theme
  • Overlay and LoadingOverlay components now support radius prop