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:

Drag images here or click to select files
Attach as many files as you like, each file should not exceed 5mb

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 { Group, Box, MediaQuery, useMantineTheme } 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 (
<Group direction="column" 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>
</Group>
);
}

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:

it's me
+2

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