8.1.0
mantinedev/mantine8.1.0Jun 9, 2025by rtivital
AI Summary
Adds presets to date pickers, improves popover middleware behavior, introduces a new use-long-press hook, adds reference areas to charts, and enhances form and slider components.
Key Highlights
- DatePicker, DatePickerInput, and DateTimePicker support custom date presets
- Popover middleware improvements fix incorrect positioning with dynamic content
- New use-long-press hook for handling long press events
- BarChart, AreaChart, and LineChart support reference areas
- Form hook gains a resetField method to reset individual fields
New Features
- DatePicker presets
- Calendar headerControlsOrder prop
- use-long-press hook
- Chart reference areas
- Form resetField method
- TagsInput isDuplicate prop
- Slider domain prop
- RangeSlider pushOnOverlap prop
- Hooks type exports
Full Release Notes
[View changelog with demos on mantine.dev website](https://mantine.dev/changelog/8-1-0)
## DatePicker presets
[DatePicker](https://mantine.dev/dates/date-picker), [DatePickerInput](https://mantine.dev/dates/date-picker-input) and [DateTimePicker](https://mantine.dev/dates/date-time-picker) now support `presets` prop that allows you to add custom date presets. Presets are displayed next to the calendar:
```tsx
import dayjs from 'dayjs';
import { DatePicker } from '@mantine/dates';
function Demo() {
const today = dayjs();
return (
<DatePicker
type="range"
presets={[
{
value: [today.subtract(2, 'day').format('YYYY-MM-DD'), today.format('YYYY-MM-DD')],
label: 'Last two days',
},
{
value: [today.subtract(7, 'day').format('YYYY-MM-DD'), today.format('YYYY-MM-DD')],
label: 'Last 7 days',
},
{
value: [today.startOf('month').format('YYYY-MM-DD'), today.format('YYYY-MM-DD')],
label: 'This month',
},
{
value: [
today.subtract(1, 'month').startOf('month').format('YYYY-MM-DD'),
today.subtract(1, 'month').endOf('month').format('YYYY-MM-DD'),
],
label: 'Last month',
},
{
value: [
today.subtract(1, 'year').startOf('year').format('YYYY-MM-DD'),
today.subtract(1, 'year').endOf('year').format('YYYY-MM-DD'),
],
label: 'Last year',
},
]}
/>
);
}
```
## Calendar headerControlsOrder
[Calendar](https://mantine.dev/dates/calendar) and other components based on it now support `headerControlsOrder` prop.
You can use `headerControlsOrder` prop to change the order of header controls. The prop accepts an array of
`'next' | 'previous' | 'level`. Note that each control can be used only once in the array.
```tsx
import { DatePicker } from '@mantine/dates';
function Demo() {
return (
<DatePicker
defaultDate="2022-02-01"
headerControlsOrder={['level', 'previous', 'next']}
styles={{
calendarHeaderLevel: {
justifyContent: 'flex-start',
paddingInlineStart: 8,
},
}}
/>
);
}
```
## Popover middlewares improvements
[Popover](https://mantine.dev/core/popover) component now handles `shift` and `flip` Floating UI
differently. Starting from 8.1.0 version, the popover dropdown position is not
changed when the popover is opened. `shift` and `flip` middlewares are used only
once to calculate the initial position of the dropdown.
This change fixes incorrect flipping/shifting behavior when there is dynamic content
in the dropdown. For example, searchable [Select](https://mantine.dev/core/select) and [DatePickerInput](https://mantine.dev/dates/date-picker-input) without `consistentWeeks` option.
## use-long-press hook
New [use-long-press](https://mantine.dev/hooks/use-long-press) hook:
```tsx
import { Button } from '@mantine/core';
import { useLongPress } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
function Demo() {
const handlers = useLongPress(() => notifications.show({ message: 'Long press triggered' }));
return <Button {...handlers}>Press and hold</Button>;
}
```
## Reference area support in charts
[BarChart](https://mantine.dev/charts/bar-chart), [AreaChart](https://mantine.dev/charts/area-chart) and [LineChart](https://mantine.dev/charts/line-chart)
components now support reference area. Reference area is a rectangular area
that can be used to highlight a specific region of the chart:
```tsx
import { ReferenceArea } from 'recharts';
import { BarChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<BarChart
h={300}
data={data}
dataKey="month"
series={[
{ name: 'Smartphones', color: 'violet.6' },
{ name: 'Laptops', color: 'blue.6' },
{ name: 'Tablets', color: 'teal.6' },
]}
>
<ReferenceArea
x1="January"
x2="March"
y1={0}
y2={1250}
yAxisId="left"
fillOpacity={0.3}
strokeOpacity={0.9}
fill="var(--mantine-color-gray-4)"
stroke="var(--mantine-color-gray-6)"
strokeWidth={1}
label={{
value: 'Q1 sales threshold',
position: 'insideTopRight',
fontSize: 12,
fill: 'var(--mantine-color-bright)',
}}
/>
</BarChart>
);
}
```
## use-form resetField handler
[use-form](https://mantine.dev/form/use-form) now has a `resetField` method that resets field value to its initial value:
```tsx
import { useForm } from '@mantine/form'
const form = useForm({ initialValues: { name: 'John Doe' } });
form.resetField('name'); // resets name field to 'John Doe'
```
## TagsInput isDuplicate prop
You can now use `isDuplicate` prop in [TagsInput](https://mantine.dev/core/tags-input) component
to control how duplicates are detected. It is a function that receives two arguments:
tag value and current tags. The function must return `true` if the value is duplicate.
Example of using `isDuplicate` to allow using the same value with different casing:
```tsx
import { TagsInput } from '@mantine/core';
function Demo() {
return (
<TagsInput
label="Press Enter to submit a tag"
placeholder="Enter tag"
isDuplicate={(tagValue, currentTags) => currentTags.some((val) => val === tagValue)}
defaultValue={['Tag', 'TAG', 'tag']}
/>
);
}
```
## Slider domain prop
[Slider](https://mantine.dev/core/slider) component now support `domain` prop that allows setting
the possible range of values independently of the `min` and `max` values:
```tsx
import { Slider } from '@mantine/core';
function Demo() {
return (
<Slider
domain={[0, 100]}
min={10}
max={90}
defaultValue={25}
marks={[
{ value: 10, label: 'min' },
{ value: 90, label: 'max' },
]}
/>
);
}
```
## RangeSlider pushOnOverlap prop
[RangeSlider](https://mantine.dev/core/slider) component now supports `pushOnOverlap` prop that defines
whether the slider should push the overlapping thumb when the user drags it.
```tsx
import { RangeSlider } from '@mantine/core';
function Demo() {
return <RangeSlider pushOnOverlap={false} defaultValue={[25, 65]} minRange={20} />;
}
```
## Hooks types exports
`@mantine/hooks` package now exports all types used in hooks options and return values.
For example, you can now import [use-uncontrolled](https://mantine.dev/hooks/use-uncontrolled) types like this:
```tsx
import type { UseUncontrolledOptions, UseUncontrolledReturnValue } from '@mantine/hooks';
```
Types exported from the library:
```tsx
interface UseUncontrolledOptions<T> {
/** Value for controlled state */
value?: T;
/** Initial value for uncontrolled state */
defaultValue?: T;
/** Final value for uncontrolled state when value and defaultValue are not provided */
finalValue?: T;
/** Controlled state onChange handler */
onChange?: (value: T) => void;
}
type UseUncontrolledReturnValue<T> = [
/** Current value */
T,
/** Handler to update the state, passes `value` and `payload` to `onChange` */
(value: T, ...payload: any[]) => void,
/** True if the state is controlled, false if uncontrolled */
boolean,
];
```
## zod v4 with use-form
You can now use zod v4 with [use-form](https://mantine.dev/form/use-form). To use zod 4:
- Update `mantine-form-zod-resolver` to `1.2.1` or later version
- Update zod to version `3.25.0` or later
- Replace `zod` imports with `zod/v4` (only if you have `zod@3` in your `package.json`)
- Replace `zodResolver` with `zod4Resolver` in your code
- All other code remains the same
Example with zod v4:
```tsx
import { z } from 'zod/v4';
import { zod4Resolver } from 'mantine-form-zod-resolver';
const schema = z.object({
name: z.string().min(2, { message: 'Name should have at least 2 letters' }),
email: z.email({ message: 'Invalid email' }),
age: z.number().min(18, { message: 'You must be at least 18 to create an account' }),
});
const form = useForm({
initialValues: {
name: '',
email: '',
age: 16,
},
validate: zod4Resolver(schema),
})
```
## Documentation updates
- [use-debounced-callback](https://mantine.dev/hooks/use-debounced-callback) documentation was updated to include new `flush` and `flushOnUnmount` features
- Documentation about exported types was added to all applicable hooks
## Other changes
- All components now support `bdrs` style prop to set border radius.
- [DateTimePicker](https://mantine.dev/dates/date-time-picker) now supports `defaultTimeValue` prop
- [Tooltip](https://mantine.dev/core/tooltip) now supports `autoContrast` prop.
- Handlers returned from [use-counter](https://mantine.dev/hooks/use-couter) are now memoized.
- Return value of [use-event-listener](https://mantine.dev/hooks/use-event-listener), [use-focus-within](https://mantine.dev/hooks/use-focus-within), [use-focus-trap](https://mantine.dev/hooks/use-focus-trap), [use-hover](https://mantine.dev/hooks/use-hover), [use-move](https://mantine.dev/hooks/use-move), [use-radial-move](https://mantine.dev/hooks/use-radial-move) changed (`React.RefObject` -> `React.RefCallback`), required to fix incorrect ref handling in several cases. For more information, see the issue on GitHub – [#7406](https://github.com/mantinedev/mantine/issues/7406).
- Deprecated `React.MutableRefObject` type was replaced with `React.RefObject` in all packages to better support React 19 types.
- `positionDependencies` prop is now deprecated in [Tooltip](https://mantine.dev/core/tooltip), [Popover](https://mantine.dev/core/popover) and other components based on Popover. The prop is no longer required and can be safely removed. `positionDependencies` prop will be removed in 9.0 release.