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.