View changelog with demos on website
Breaking changes
- MediaQuery now requires passing
styles
object and does not hide child element by default - Styles API static selectors no longer use kebab case (was
.mantine-text-input-root
, now.mantine-TextInput-root
)
Configure emotion with MantineProvider
You can now set emotion cache options via MantineProvider:
<MantineProvider emotionOptions={{ key: "mantine", prepend: false }}>
<App />
</MantineProvider>
With these options you can change styles insertion point (from 3.1 styles are prepended to head)
and configure stylis plugins. For example, you can use stylis-plugin-rtl to add rtl support:
import { MantineProvider } from "@mantine/core";
import rtlPlugin from "stylis-plugin-rtl";
function Demo() {
return (
<MantineProvider
emotionOptions={{ key: "mantine", stylisPlugins: [rtlPlugin] }}
>
<App />
</MantineProvider>
);
}
Styles API on MantineProvider
You can now add styles to components with MantineProvider.
Styles will be added to every matching component rendered inside MantineProvider:
import { MantineProvider, Button, Badge } from "@mantine/core";
function Demo() {
return (
<MantineProvider
styles={{
Button: (theme) => ({
// Shared button styles are applied to all buttons
root: { height: 42, padding: "0 30px" },
// These styles are applied only to buttons with outline variant
outline: {
// You can use any selectors inside (the same way as in createStyles function)
"&:hover": {
backgroundColor:
theme.colorScheme === "dark"
? theme.colors.dark[8]
: theme.colors.gray[0],
},
},
}),
// Use raw styles object if you do not need theme dependency
Badge: {
dot: {
borderWidth: 2,
},
},
}}
>
<Button variant="outline">Outline button</Button>
<Button variant="filled">Filled button</Button>
<Badge variant="dot">Dot badge</Badge>
</MantineProvider>
);
}
Inline styles with emotion
styles
prop will no longer add inline styles, instead styles will be converted to emotion format.
This means that you now can subscribe to theme
and use nested selectors in styles
:
<Button
styles={(theme) => ({
outline: {
"&:hover": {
backgroundColor:
theme.colorScheme === "dark"
? theme.colors.dark[8]
: theme.colors.dark[0],
},
},
root: {
height: 56,
},
})}
>
My custom button
</Button>
sx prop
All components now support sx
prop. You can add styles to root element and subscribe to theme with it:
<Button
sx={(theme) => ({
borderColor: theme.colors.blue[9],
"&:hover": {
backgroundColor: theme.colors.blue[7],
},
})}
>
Button with sx styles
</Button>
use-css hook
New use-css hook is a simpler alternative to createStyles
function.
Hook returns css
and cx
functions. css
function accepts styles object and returns class name:
import { useCss, Button } from "@mantine/core";
function Demo({ active }) {
const { css, cx } = useCss();
return (
<Button
className={cx(css({ backgroundColor: "red", opacity: 1 }), {
[css({ opacity: 1 })]: active,
})}
>
Custom button
</Button>
);
}
New components and hooks
New AppShell component allows you create responsive app shell with fixed or static position:
With Skeleton component you can create placeholders to indicate loading state:
<Skeleton height={50} circle mb="xl" />
<Skeleton height={8} radius="xl" />
<Skeleton height={8} mt={6} radius="xl" />
<Skeleton height={8} mt={6} width="70%" radius="xl" />
New use-scroll-into-view hook lets you scroll given node into view within scrollable container or body element:
import { useScrollIntoView } from '@mantine/hooks';
import { Button, Paper } from '@mantine/core';
function Demo() {
const { scrollIntoView, targetRef, scrollableRef } = useScrollIntoView();
return (
<>
<Paper ref={scrollableRef} style={{ overflowY: 'scroll', height: 300, flex: 1 }}>
<Paper ref={targetRef}>Scroll me into view<</Paper>
</Paper>
<Button onClick={() => scrollIntoView()}>Scroll to target</Button>
</>
);
}
Box component allows you to utilize new sx
prop to style any component or element:
<Box
sx={(theme) => ({
backgroundColor:
theme.colorScheme === "dark"
? theme.colors.dark[6]
: theme.colors.gray[0],
textAlign: "center",
padding: theme.spacing.xl,
borderRadius: theme.radius.md,
cursor: "pointer",
"&:hover": {
backgroundColor:
theme.colorScheme === "dark"
? theme.colors.dark[5]
: theme.colors.gray[1],
},
})}
>
Box lets you add inline styles with sx prop
</Box>
New features
- Select and MultiSelect components now support custom scrollbars with react-custom-scrollbars package
- Collapse component now supports dynamic children – you can now use this feature in all components that are built with Collapse
- MediaQuery component now supports adding custom styles and subscribing to custom media queries
- use-list-state hook now has new
applyWhere
handler - use-form hook now supports
values
on validation rule - Slider and RangeSlider components were migrated to use-move hook and now supports showing label on hover (new default behavior)
- Add better focus management to Popover – now focus will be returned to last active element (made with use-focus-return hook)
- AvatarsGroup - now supports
total
prop to explicitly override the truncated length. - Add
onDropdownOpen
andonDropdownClose
handlers support to Select, MultiSelect and Autocomplete components
Bug fixes
- Fix incorrect focus handling in Menu, DatePicker and DateRangePicker which resulted in focus not being shifted to control/input when dropdown was closed
- Fix incorrect MultiSelect creatable filtering logic when the same item can be created multiple times
- Fix layout jumping on Windows and Linux when overlay components with scroll lock are opened (Modal and Drawer), see use-scroll-lock documentation to learn how to offset elements with fixed position
- Fix DatePicker dropdown not updating position when used near bottom edge of viewport
- Fix incorrect random ids generated during server side rendering in Next.js
- Prevent page from rendering twice in
@mantine/next
package