Version v9.8.0

Support Mantine development

You can now sponsor Mantine development with OpenCollective. All funds are used to improve Mantine and create new features and components.

Sponsor Mantine

@mantine/emoji package

New @mantine/emoji package provides emoji picker components. It works with any emoji data source through adapters, emoji-mart and emojibase-data adapters are included.

EmojiPicker

EmojiPicker displays a searchable emoji grid with category navigation, skin tone selector, and emoji preview.

😀Grinning Face
import data from '@emoji-mart/data';
import { emojiMartAdapter, EmojiPicker } from '@mantine/emoji';

const emojiData = emojiMartAdapter(data);

function Demo() {
  return (
    <EmojiPicker
      data={emojiData}
      onEmojiSelect={(emoji) => console.log(emoji)}
    />
  );
}

EmojiPickerInput

EmojiPickerInput is an input with an emoji picker dropdown. It supports all standard input features like labels, descriptions, error messages, and sizes.

Input description

Variant
Size
Radius
import data from '@emoji-mart/data';
import { emojiMartAdapter, EmojiPickerInput } from '@mantine/emoji';

const emojiData = emojiMartAdapter(data);

function Demo() {
  return <EmojiPickerInput data={emojiData} label="Input label" description="Input description" placeholder="Select emoji" />;
}

EmojiPickerPopover

EmojiPickerPopover renders an emoji picker inside a popover dropdown. Use it to build custom emoji picker triggers.

import { useState } from 'react';
import { ActionIcon } from '@mantine/core';
import data from '@emoji-mart/data';
import { emojiMartAdapter, EmojiPickerPopover } from '@mantine/emoji';

const emojiData = emojiMartAdapter(data);

function Demo() {
  const [emoji, setEmoji] = useState<string | null>(null);

  return (
    <EmojiPickerPopover
      data={emojiData}
      onEmojiSelect={(e) => setEmoji(e.emoji)}
    >
      <ActionIcon variant="default" size="lg">
        {emoji || '☺'}
      </ActionIcon>
    </EmojiPickerPopover>
  );
}

Diff component

New Diff component highlights differences between two strings. It supports unified and split (side-by-side) display modes, configurable diff granularity (characters, words, or lines), and context line collapsing.

1- import { useState } from 'react';
1+ import { useReducer } from 'react';
22
33function Counter() {
4- const [count, setCount] = useState(0);
4+ const [count, dispatch] = useReducer(reducer, 0);
55 return (
6- <button onClick={() => setCount(count + 1)}>
6+ <button onClick={() => dispatch({ type: 'increment' })}>
77 Count: {count}
88 </button>
99 );
1010}
import { Diff } from '@mantine/code-highlight';
import { currentCode, previousCode } from './data';

function Demo() {
  return <Diff previousValue={previousCode} currentValue={currentCode} />;
}

PhoneInput component

New PhoneInput component provides an international phone number input with country selector, auto-detection, and formatting masks.

import { PhoneInput } from '@mantine/core';

function Demo() {
  return (
    <PhoneInput
      label="Phone number"
      placeholder="Your phone number"
      defaultCountry="us"
      renderFlag={(country) => (
        <img
          src={`https://hatscripts.github.io/circle-flags/flags/${country?.iso2 ?? 'xx'}.svg`}
          alt={country?.name ?? 'Select country'}
          style={{ width: 20, height: 20, borderRadius: 20 }}
        />
      )}
    />
  );
}

MaskedDateInput component

New MaskedDateInput component provides a date input with individual masked fields for day, month, and year. It supports configurable field order, custom separators, optional time fields, and a calendar dropdown for date selection.

//
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return <MaskedDateInput label="Date of birth" />;
}

QuarterPicker and QuarterPickerInput components

New QuarterPicker and QuarterPickerInput components allow picking quarters, multiple quarters and quarters ranges. They work the same way as MonthPicker and MonthPickerInput; the value is the first day of the selected quarter in YYYY-MM-DD format.

import { useState } from 'react';
import { QuarterPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return <QuarterPicker value={value} onChange={setValue} />;
}

import { useState } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <QuarterPickerInput
      label="Pick date"
      placeholder="Pick date"
      value={value}
      onChange={setValue}
    />
  );
}

WeekPicker and WeekPickerInput components

New WeekPicker and WeekPickerInput components allow picking weeks, multiple weeks and weeks ranges. Clicking any day selects the whole week, the value is the first day of the week according to firstDayOfWeek in YYYY-MM-DD format.

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return <WeekPicker value={value} onChange={setValue} />;
}

import { useState } from 'react';
import { WeekPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <WeekPickerInput
      label="Pick date"
      placeholder="Pick date"
      value={value}
      onChange={setValue}
    />
  );
}

use-active-element hook

New use-active-element hook tracks the element that currently has focus. Use it to build focus-aware UI or to disable global keyboard shortcuts while the user is typing:

Focused element: null

import { Code, Group, Text, Textarea, TextInput } from '@mantine/core';
import { useActiveElement } from '@mantine/hooks';

function describe(element: Element | null) {
  if (!element) {
    return 'null';
  }

  return element.id ? `${element.tagName.toLowerCase()}#${element.id}` : element.tagName.toLowerCase();
}

function Demo() {
  const activeElement = useActiveElement();

  return (
    <>
      <Text>
        Focused element: <Code>{describe(activeElement)}</Code>
      </Text>

      <Group grow mt="md">
        <TextInput id="first-name" label="First name" placeholder="First name" />
        <TextInput id="last-name" label="Last name" placeholder="Last name" />
      </Group>

      <Textarea id="message" mt="md" label="Message" placeholder="Your message" />
    </>
  );
}

use-browser-language hook

New use-browser-language hook returns the browser language and updates when the user changes it. Use it to pick a default locale for formatting or translations:

Your browser language: unknown

import { Code, Text } from '@mantine/core';
import { useBrowserLanguage } from '@mantine/hooks';

function Demo() {
  const language = useBrowserLanguage();

  return (
    <Text>
      Your browser language: <Code>{language ?? 'unknown'}</Code>
    </Text>
  );
}

Mentions component

New Mentions component is a textarea that opens a suggestions dropdown when the user types @ or any other trigger. Picked mentions are stored in the value as @[Display](id) markup, the user sees only the display text:

import { useState } from 'react';
import { Mentions } from '@mantine/core';

const users = [
  { id: 'walter', display: 'Walter White' },
  { id: 'jesse', display: 'Jesse Pinkman' },
  { id: 'saul', display: 'Saul Goodman' },
  { id: 'gus', display: 'Gustavo Fring' },
];

function Demo() {
  const [value, setValue] = useState('Hey @[Walter White](walter), are you ready?');

  return (
    <Mentions
      label="Comment"
      placeholder="Type @ to mention someone"
      value={value}
      onChange={(payload) => setValue(payload.value)}
      minRows={3}
    >
      <Mentions.Mention trigger="@" data={users} />
    </Mentions>
  );
}

Other changes

  • DayView and WeekView support slotLabelInterval prop to display time labels more often than once per hour
  • DayView and WeekView businessHours prop accepts exact minutes, business hours colors can be changed with CSS variables
  • MobileMonthView supports withWeekendDays prop to hide weekend days
  • ScrollArea supports --scrollarea-offset-size CSS variable to change the gap reserved by offsetScrollbars
  • Popover and components based on it support clickOutsideCapture prop to close the dropdown when the click target stops event propagation
  • getUploadImageExtension in @mantine/tiptap uploads images embedded in pasted HTML, use shouldUploadPastedImage option to control which images are uploaded
  • Keyboard navigation in DatePicker and other @mantine/dates pickers has been improved: arrow keys move focus across months and focus returns to the input when the dropdown closes
  • @mantine/form exports UseContextForm type
  • Notifications support autoCloseProgressPosition prop to display the auto close progress line at the top of the notification