Skip to content

fix(deps): update mantine monorepo to v9 - #180

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-mantine-monorepo
Open

fix(deps): update mantine monorepo to v9#180
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-mantine-monorepo

Conversation

@renovate

@renovate renovate Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@mantine/core (source) ^8.3.5^9.0.0 age confidence
@mantine/form (source) ^8.3.6^9.0.0 age confidence

Release Notes

mantinedev/mantine (@​mantine/core)

v9.6.0

Compare Source

View changelog with demos on mantine.dev website

Support Mantine development

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

@​mantine/lightbox package

New @​mantine/lightbox package – a full-screen media lightbox with carousel navigation,
zoom, thumbnails, toolbar customization, and store-based API. Supports image, video, and custom slides:

import '@mantine/lightbox/styles.css';
import { useState } from 'react';
import { Image, SimpleGrid } from '@mantine/core';
import { Lightbox, LightboxSlideData } from '@mantine/lightbox';

const images = [
  'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-1.png',
  'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-2.png',
  'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-3.png',
  'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-4.png',
  'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-5.png',
];

const slides: LightboxSlideData[] = images.map((src) => ({ src }));

function Demo() {
  const [opened, setOpened] = useState(false);
  const [index, setIndex] = useState(0);

  return (
    <>
      <Lightbox
        opened={opened}
        onClose={() => setOpened(false)}
        slides={slides}
        currentIndex={index}
        onIndexChange={setIndex}
      />

      <SimpleGrid cols={3}>
        {images.map((src, i) => (
          <Image
            key={src}
            src={src}
            radius="md"
            style={{ cursor: 'pointer' }}
            onClick={() => {
              setIndex(i);
              setOpened(true);
            }}
          />
        ))}
      </SimpleGrid>
    </>
  );
}

Key features:

  • Zoom – click to zoom on desktop, double-tap on mobile, scroll wheel and pinch gestures
  • Thumbnails – bottom thumbnail strip with active indicator
  • Store API – mount once, open from anywhere (same pattern as Spotlight and Notifications)
  • Video slides – native video player with auto-pause on navigation
  • Custom slides – render anything with custom thumbnails
  • Transitions – animated open and close with configurable transitionProps (same API as Modal)
  • Keyboard shortcuts – Escape, arrows, F/T/Z for fullscreen/thumbnails/zoom
  • Localization – every string is defined in the labels prop
Notifications custom rendering

Notifications now support renderNotification prop that allows you to completely
replace the default notification with custom content. All animations (enter, exit, drag dismiss)
are preserved for custom notifications:

import { Avatar, Button, Group, rem, Text } from '@mantine/core';
import { notifications } from '@mantine/notifications';

function Demo() {
  return (
    <Group justify="center">
      <Button
        onClick={() =>
          notifications.show({
            autoClose: false,
            renderNotification: (notification) => (
              <div
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: rem(12),
                  padding: rem(16),
                  borderRadius: rem(8),
                  backgroundColor: 'var(--mantine-color-body)',
                  border: '1px solid var(--mantine-color-default-border)',
                  boxShadow: 'var(--mantine-shadow-lg)',
                  userSelect: 'none',
                }}
              >
                <Avatar src={null} radius="xl" color="blue">
                  DM
                </Avatar>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <Text size="sm" fw={600}>
                    Dan sent you a message
                  </Text>
                  <Text size="xs" c="dimmed" lineClamp={1}>
                    Hey, are you free for a quick call?
                  </Text>
                  <Group gap="xs" mt={8}>
                    <Button
                      size="compact-xs"
                      variant="filled"
                      onClick={() =>
                        notifications.hide(notification.id!)
                      }
                    >
                      Reply
                    </Button>
                    <Button
                      size="compact-xs"
                      variant="default"
                      onClick={() =>
                        notifications.hide(notification.id!)
                      }
                    >
                      Dismiss
                    </Button>
                  </Group>
                </div>
              </div>
            ),
            message: '',
          })
        }
      >
        Show custom notification
      </Button>
    </Group>
  );
}
Notifications stacked layout

Notifications now support layout="stacked" prop that displays notifications in a stacked
layout where only the latest notification is fully visible, and older notifications peek out behind it:

import { Button, Group } from '@mantine/core';
import { Notifications, notifications } from '@mantine/notifications';

function Demo() {
  return (
    <>
      {/* Replace your existing Notifications with layout="stacked" */}
      <Notifications layout="stacked" />
      <Group justify="center">
        <Button
          onClick={() => {
            notifications.show({
              title: 'New notification',
              message: 'This notification is part of a stacked layout',
            });
          }}
        >
          Show stacked notification
        </Button>
      </Group>
    </>
  );
}
ActionBar component

New ActionBar component – a fixed-position bottom bar
for bulk selection actions. Designed to be controlled by table or checkbox
selections, it provides a set of actions that can be performed on selected items.

import { useState } from 'react';
import { ActionBar, Button, Checkbox, Table, Text } from '@mantine/core';

const elements = [
  { position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
  { position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
  { position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
  { position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
  { position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
];

function Demo() {
  const [selection, setSelection] = useState<number[]>([]);

  const toggleRow = (position: number) =>
    setSelection((current) =>
      current.includes(position)
        ? current.filter((item) => item !== position)
        : [...current, position]
    );

  const toggleAll = () =>
    setSelection((current) =>
      current.length === elements.length ? [] : elements.map((element) => element.position)
    );

  const rows = elements.map((element) => (
    <Table.Tr
      key={element.position}
      bg={selection.includes(element.position) ? 'var(--mantine-color-blue-light)' : undefined}
    >
      <Table.Td>
        <Checkbox
          aria-label="Select row"
          checked={selection.includes(element.position)}
          onChange={() => toggleRow(element.position)}
        />
      </Table.Td>
      <Table.Td>{element.position}</Table.Td>
      <Table.Td>{element.name}</Table.Td>
      <Table.Td>{element.symbol}</Table.Td>
      <Table.Td>{element.mass}</Table.Td>
    </Table.Tr>
  ));

  return (
    <>
      <Table>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>
              <Checkbox
                aria-label="Select all"
                checked={selection.length === elements.length}
                indeterminate={selection.length > 0 && selection.length !== elements.length}
                onChange={toggleAll}
              />
            </Table.Th>
            <Table.Th>Element position</Table.Th>
            <Table.Th>Element name</Table.Th>
            <Table.Th>Symbol</Table.Th>
            <Table.Th>Atomic mass</Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>{rows}</Table.Tbody>
      </Table>

      <ActionBar opened={selection.length > 0} onClose={() => setSelection([])} shadow="md">
        <Text size="sm">{selection.length} selected</Text>
        <ActionBar.Divider />
        <Button variant="default" size="compact-sm">
          Delete
        </Button>
        <Button variant="default" size="compact-sm">
          Move
        </Button>
        <Button variant="default" size="compact-sm">
          Archive
        </Button>
        <ActionBar.CloseButton />
      </ActionBar>
    </>
  );
}
RichTextEditor table controls

RichTextEditor now includes a set of controls for editing tables. Install and register the
Tiptap table extension (TableKit), then add
the controls to the toolbar. RichTextEditor.TableInsert opens a grid to pick the table size, and the
other controls add/remove rows and columns, toggle header row/column and merge/split cells. All table
controls are automatically disabled when the cursor is not inside a table:

import { TableKit } from '@tiptap/extension-table';
import { useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import { RichTextEditor } from '@mantine/tiptap';

function Demo() {
  const editor = useEditor({
    extensions: [StarterKit, TableKit],
    content: `
      <table>
        <tbody>
          <tr><th><p>Framework</p></th><th><p>Language</p></th></tr>
          <tr><td><p>Mantine</p></td><td><p>TypeScript</p></td></tr>
          <tr><td><p>Tiptap</p></td><td><p>TypeScript</p></td></tr>
        </tbody>
      </table>
      <p></p>
`,
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar sticky>
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TableInsert />
          <RichTextEditor.TableDelete />
        </RichTextEditor.ControlsGroup>

        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TableColumnBefore />
          <RichTextEditor.TableColumnAfter />
          <RichTextEditor.TableColumnDelete />
        </RichTextEditor.ControlsGroup>

        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TableRowBefore />
          <RichTextEditor.TableRowAfter />
          <RichTextEditor.TableRowDelete />
        </RichTextEditor.ControlsGroup>

        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TableToggleHeaderRow />
          <RichTextEditor.TableToggleHeaderColumn />
          <RichTextEditor.TableMergeCells />
          <RichTextEditor.TableSplitCell />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>

      <RichTextEditor.Content />
    </RichTextEditor>
  );
}
RichTextEditor Details control

RichTextEditor now supports collapsible sections. Install and register the
Tiptap details extension (Details,
DetailsSummary and DetailsContent), then add RichTextEditor.Details to the toolbar. The control
wraps the current block in a collapsible details node, or removes it when the cursor is already inside
one:

import { Details, DetailsSummary, DetailsContent } from '@tiptap/extension-details';
import { useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import { RichTextEditor } from '@mantine/tiptap';

function Demo() {
  const editor = useEditor({
    extensions: [StarterKit, Details, DetailsSummary, DetailsContent],
    content: `
      <details>
        <summary>Shipping and delivery</summary>
        <p>Orders are processed within 1–2 business days and delivered in 3–5 business days.</p>
      </details>
      <details>
        <summary>Returns and refunds</summary>
        <p>You can return any item within 30 days of delivery for a full refund.</p>
      </details>
      <p></p>
`,
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar sticky>
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.Bold />
          <RichTextEditor.Italic />
          <RichTextEditor.Underline />
        </RichTextEditor.ControlsGroup>

        <RichTextEditor.ControlsGroup>
          <RichTextEditor.Details />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>

      <RichTextEditor.Content />
    </RichTextEditor>
  );
}

To support the control, Typography now styles details and summary elements –
a border, padding and a custom disclosure triangle. This applies to all details elements inside
Typography, not just those created by the editor. All of the new selectors have zero specificity
(:where()), so they can be overridden without !important.

RichTextEditor InvisibleCharacters control

RichTextEditor can now display formatting marks. Install and register the
Tiptap invisible characters extension,
then add RichTextEditor.InvisibleCharacters to the toolbar. The control toggles the visibility of
spaces, paragraph breaks and hard breaks, and reflects the current visibility as its active state:

import InvisibleCharacters from '@tiptap/extension-invisible-characters';
import { useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import { RichTextEditor } from '@mantine/tiptap';

function Demo() {
  const editor = useEditor({
    extensions: [StarterKit, InvisibleCharacters.configure({ visible: false })],
    content: `
      <p>Toggle the control to reveal spaces and paragraph breaks.</p>
      <p>Each space becomes a dot and every paragraph ends with a pilcrow.</p>
`,
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar sticky>
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.Bold />
          <RichTextEditor.Italic />
          <RichTextEditor.Underline />
        </RichTextEditor.ControlsGroup>

        <RichTextEditor.ControlsGroup>
          <RichTextEditor.InvisibleCharacters />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>

      <RichTextEditor.Content />
    </RichTextEditor>
  );
}
GaugeChart component

New GaugeChart component – a radial gauge chart for KPI and status display.
Supports threshold sections, target marker, custom labels, and configurable arc angles.

import { GaugeChart } from '@mantine/charts';

function Demo() {
  return <GaugeChart value={72} size={200} thickness={12} />;
}
WaffleChart component

New WaffleChart component – a part-to-whole grid chart with colored cells.
Simpler and more compact alternative to pie/donut charts for displaying percentages and proportions.

// Demo.tsx
import { WaffleChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return <WaffleChart data={data} />;
}

// data.ts
import { WaffleChartCell } from '@mantine/charts';

export const data: WaffleChartCell[] = [
  { name: 'Chrome', value: 65, color: 'blue' },
  { name: 'Safari', value: 19, color: 'teal' },
  { name: 'Firefox', value: 10, color: 'orange' },
  { name: 'Other', value: 6, color: 'gray' },
];
MatrixChart component

New MatrixChart component – a generic x/y heatmap with categorical axes.
Each cell is colored based on a value, useful for visualizing patterns in two-dimensional categorical data.

// Demo.tsx
import { MatrixChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <MatrixChart
      data={data}
      yLabels={['James', 'Mary', 'Robert', 'Linda', 'Michael', 'Sarah', 'David', 'Emma']}
      withYLabels
      withTooltip
      getTooltipLabel={({ x, y, value }) =>
        `${y}, Mar ${x}: ${value === null ? 'No contributions' : `${value} contribution${value > 1 ? 's' : ''}`}`
      }
    />
  );
}

// data.ts
import { MatrixChartCell } from '@mantine/charts';

export const data: MatrixChartCell[] = [
  { x: '1', y: 'James', value: 7 },
  { x: '2', y: 'James', value: 10 },
  { x: '3', y: 'James', value: 2 },
  { x: '4', y: 'James', value: 10 },
  { x: '5', y: 'James', value: 8 },
  { x: '6', y: 'James', value: null },
  { x: '7', y: 'James', value: null },
  { x: '8', y: 'James', value: 6 },
  { x: '9', y: 'James', value: 2 },
  { x: '10', y: 'James', value: 8 },
  { x: '11', y: 'James', value: 1 },
  { x: '12', y: 'James', value: 3 },
  { x: '13', y: 'James', value: 7 },
  { x: '14', y: 'James', value: null },
  { x: '15', y: 'James', value: 9 },
  { x: '16', y: 'James', value: 10 },
  { x: '17', y: 'James', value: null },
  { x: '18', y: 'James', value: 1 },
  { x: '19', y: 'James', value: 8 },
  { x: '20', y: 'James', value: null },
  { x: '21', y: 'James', value: null },
  { x: '22', y: 'James', value: 5 },
  { x: '23', y: 'James', value: 8 },
  { x: '24', y: 'James', value: 2 },
  { x: '25', y: 'James', value: 5 },
  { x: '26', y: 'James', value: 6 },
  { x: '27', y: 'James', value: null },
  { x: '28', y: 'James', value: null },
  { x: '29', y: 'James', value: 7 },
  { x: '30', y: 'James', value: 7 },
  { x: '31', y: 'James', value: 6 },
  { x: '1', y: 'Mary', value: 3 },
  { x: '2', y: 'Mary', value: 1 },
  // ... remaining data
];
CandlestickChart component

New CandlestickChart component – a financial OHLC chart that displays
open, high, low and close values as candles. Candles are colored based on their direction, the wick
shows the high–low range and the body shows the open–close range. Supports custom colors, data keys,
reference lines, axis labels, tooltip labels and value formatting.

// Demo.tsx
import { CandlestickChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return <CandlestickChart h={300} data={data} dataKey="date"  tickLine="y" gridAxis="x" withXAxis={true} withYAxis={true} withTooltip={true} />;
}

// data.ts
export const data = [
  { date: 'Mar 01', open: 136, high: 142, low: 133, close: 140 },
  { date: 'Mar 02', open: 140, high: 145, low: 138, close: 139 },
  { date: 'Mar 03', open: 139, high: 141, low: 129, close: 131 },
  { date: 'Mar 04', open: 131, high: 134, low: 124, close: 125 },
  { date: 'Mar 05', open: 125, high: 133, low: 124, close: 132 },
  { date: 'Mar 06', open: 132, high: 138, low: 131, close: 137 },
  { date: 'Mar 07', open: 137, high: 137, low: 128, close: 129 },
  { date: 'Mar 08', open: 129, high: 135, low: 127, close: 134 },
  { date: 'Mar 09', open: 134, high: 148, low: 133, close: 146 },
  { date: 'Mar 10', open: 146, high: 152, low: 144, close: 151 },
  { date: 'Mar 11', open: 151, high: 154, low: 143, close: 145 },
  { date: 'Mar 12', open: 145, high: 149, low: 142, close: 148 },
  { date: 'Mar 13', open: 148, high: 156, low: 147, close: 155 },
  { date: 'Mar 14', open: 155, high: 158, low: 150, close: 152 },
  { date: 'Mar 15', open: 152, high: 153, low: 141, close: 143 },
  { date: 'Mar 16', open: 143, high: 147, low: 139, close: 146 },
  { date: 'Mar 17', open: 146, high: 160, low: 145, close: 159 },
  { date: 'Mar 18', open: 159, high: 164, low: 156, close: 157 },
  { date: 'Mar 19', open: 157, high: 162, low: 153, close: 161 },
  { date: 'Mar 20', open: 161, high: 168, low: 160, close: 166 },
];
Charts reference areas

AreaChart, BarChart, LineChart,
CompositeChart and ScatterChart now support the
referenceAreas prop that highlights a rectangular region of the plot – a weekend band, a target
range, a threshold zone and similar annotations. Each area is bounded by x1/x2 and/or y1/y2
data values (omit one pair to span the full opposite axis) and supports a theme color and a label.

// Demo.tsx
import { AreaChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <AreaChart
      h={300}
      data={data}
      dataKey="date"
      type="stacked"
      series={[
        { name: 'Apples', color: 'indigo.6' },
        { name: 'Oranges', color: 'blue.6' },
        { name: 'Tomatoes', color: 'teal.6' },
      ]}
      referenceAreas={[
        { x1: 'Mar 23', x2: 'Mar 25', color: 'red.6', label: 'Weekend' },
      ]}
    />
  );
}

// data.ts
export const data = [
  {
    date: 'Mar 22',
    Apples: 2890,
    Oranges: 2338,
    Tomatoes: 2452,
  },
  {
    date: 'Mar 23',
    Apples: 2756,
    Oranges: 2103,
    Tomatoes: 2402,
  },
  {
    date: 'Mar 24',
    Apples: 3322,
    Oranges: 986,
    Tomatoes: 1821,
  },
  {
    date: 'Mar 25',
    Apples: 3470,
    Oranges: 2108,
    Tomatoes: 2809,
  },
  {
    date: 'Mar 26',
    Apples: 3129,
    Oranges: 1726,
    Tomatoes: 2290,
  },
];
Charts reference dots

AreaChart, BarChart, LineChart,
CompositeChart and ScatterChart now support the
referenceDots prop that marks individual points on the plot – a peak, an event, a record value or an
anomaly. Each dot is positioned by x/y data coordinates and supports a radius, a theme color and a
label. Reference dots are rendered on top of the chart series.

// Demo.tsx
import { AreaChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <AreaChart
      h={300}
      data={data}
      dataKey="date"
      series={[
        { name: 'Apples', color: 'indigo.6' },
        { name: 'Oranges', color: 'blue.6' },
        { name: 'Tomatoes', color: 'teal.6' },
      ]}
      referenceDots={[
        { x: 'Mar 25', y: 3470, color: 'red.6', label: 'Peak' },
      ]}
    />
  );
}

// data.ts
export const data = [
  {
    date: 'Mar 22',
    Apples: 2890,
    Oranges: 2338,
    Tomatoes: 2452,
  },
  {
    date: 'Mar 23',
    Apples: 2756,
    Oranges: 2103,
    Tomatoes: 2402,
  },
  {
    date: 'Mar 24',
    Apples: 3322,
    Oranges: 986,
    Tomatoes: 1821,
  },
  {
    date: 'Mar 25',
    Apples: 3470,
    Oranges: 2108,
    Tomatoes: 2809,
  },
  {
    date: 'Mar 26',
    Apples: 3129,
    Oranges: 1726,
    Tomatoes: 2290,
  },
];

Note that referenceLines in AreaChart are now rendered on top of the areas
instead of behind them, which makes them consistent with BarChart, LineChart, CompositeChart
and ScatterChart, where reference lines were already painted over the series.

AreaChart streamgraph

AreaChart now supports type="stream" that renders a streamgraph (also known
as ThemeRiver) – a stacked area chart whose baseline flows around a central axis instead of being
fixed to zero, producing the characteristic organic "river" shape. The y-axis is hidden by default
for this type since its floating baseline makes the values not meaningful to read off:

// Demo.tsx
import { AreaChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <AreaChart
      h={300}
      data={data}
      dataKey="month"
      type="stream"
      series={[
        { name: 'Apples', color: 'indigo.6' },
        { name: 'Oranges', color: 'blue.6' },
        { name: 'Tomatoes', color: 'teal.6' },
        { name: 'Grapes', color: 'grape.6' },
      ]}
    />
  );
}

// data.ts
export const data = [
  { month: 'Jan', Apples: 220, Oranges: 140, Tomatoes: 90, Grapes: 60 },
  { month: 'Feb', Apples: 260, Oranges: 180, Tomatoes: 120, Grapes: 90 },
  { month: 'Mar', Apples: 300, Oranges: 240, Tomatoes: 180, Grapes: 140 },
  { month: 'Apr', Apples: 340, Oranges: 320, Tomatoes: 260, Grapes: 200 },
  { month: 'May', Apples: 380, Oranges: 420, Tomatoes: 360, Grapes: 280 },
  { month: 'Jun', Apples: 420, Oranges: 520, Tomatoes: 460, Grapes: 360 },
  { month: 'Jul', Apples: 400, Oranges: 560, Tomatoes: 520, Grapes: 420 },
  { month: 'Aug', Apples: 360, Oranges: 520, Tomatoes: 560, Grapes: 460 },
  { month: 'Sep', Apples: 300, Oranges: 440, Tomatoes: 520, Grapes: 420 },
  { month: 'Oct', Apples: 260, Oranges: 340, Tomatoes: 440, Grapes: 360 },
  { month: 'Nov', Apples: 220, Oranges: 260, Tomatoes: 340, Grapes: 280 },
  { month: 'Dec', Apples: 200, Oranges: 200, Tomatoes: 260, Grapes: 200 },
];
ScatterChart right Y axis

ScatterChart now supports the withRightYAxis prop that displays an
additional Y axis on the right side of the chart, configurable with rightYAxisProps and
rightYAxisLabel. Bind data series to the right Y axis by setting yAxisId: 'right' in the data
object – series without yAxisId are bound to the left Y axis. Both axes use the same dataKey.y
value, but their scales are calculated independently from the series assigned to them:

// Demo.tsx
import { ScatterChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <ScatterChart
      h={350}
      data={data}
      dataKey={{ x: 'month', y: 'value' }}
      withLegend
      withRightYAxis
      xAxisLabel="Month"
      yAxisLabel="Revenue"
      rightYAxisLabel="Conversion rate"
      rightYAxisProps={{ unit: '%' }}
    />
  );
}

// data.ts
export const data = [
  {
    color: 'indigo.6',
    name: 'Revenue',
    data: [
      { month: 1, value: 1200 },
      { month: 2, value: 1400 },
      { month: 3, value: 1350 },
      { month: 4, value: 1800 },
      { month: 5, value: 2100 },
      { month: 6, value: 1950 },
      { month: 7, value: 2400 },
      { month: 8, value: 2650 },
      { month: 9, value: 2300 },
      { month: 10, value: 2800 },
      { month: 11, value: 3100 },
      { month: 12, value: 3400 },
    ],
  },
  {
    color: 'teal.6',
    name: 'Conversion rate',
    yAxisId: 'right',
    data: [
      { month: 1, value: 3.4 },
      { month: 2, value: 3.9 },
      { month: 3, value: 3.1 },
      { month: 4, value: 4.2 },
      { month: 5, value: 4.8 },
      { month: 6, value: 4.1 },
      { month: 7, value: 5.3 },
      { month: 8, value: 5.9 },
      { month: 9, value: 5.1 },
      { month: 10, value: 6.2 },
      { month: 11, value: 6.8 },
      { month: 12, value: 7.4 },
    ],
  },
];
Stepper labelPosition

Stepper component now supports the labelPosition prop. Set labelPosition="bottom"
to display the step label and description below the step icon:

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

function Demo() {
  const [active, setActive] = useState(1);
  return (
    <Stepper active={active} onStepClick={setActive} labelPosition="bottom">
      <Stepper.Step label="Account" />
      <Stepper.Step label="Verification" />
      <Stepper.Step label="Access" />
    </Stepper>
  );
}
Cascader safe area polygon

Cascader with expandTrigger="hover" now keeps the open column in place while the
cursor moves diagonally toward it – options that the cursor passes over on the way no longer replace
it. Set safeAreaPolygon={false} to expand on every hover immediately, or pass an object to configure
Floating UI safePolygon options:

import { Cascader, useMatches } from '@mantine/core';
import { data } from './data';

function Demo() {
  const withColumns = useMatches({ base: false, sm: true });
  return (
    <Cascader
      withColumns={withColumns}
      expandTrigger="hover"
      safeAreaPolygon={false}
      label="Location"
      placeholder="Hover to expand"
      data={data}
    />
  );
}
YearView renderDay

YearView now supports the renderDay prop that replaces the entire content of
a day cell. The function is called with the day date in YYYY-MM-DD format and the events grouped on
that day – the same list that is used to render the default indicators, but without the three items
limit. This makes it possible to display counts, badges or icons instead of the default dots:

// Demo.tsx
import dayjs from 'dayjs';
import { YearView } from '@mantine/schedule';
import { events } from './data';

function Demo() {
  return (
    <YearView
      date={new Date()}
      events={events}
      renderDay={(date, dayEvents) => (
        <>
          {dayjs(date).date()}

          {dayEvents.length > 0 && (
            <div
              style={{
                position: 'absolute',
                bottom: 0,
                insetInlineEnd: 0,
                minWidth: 12,
                height: 12,
                borderRadius: 12,
                fontSize: 9,
                lineHeight: '12px',
                fontWeight: 700,
                textAlign: 'center',
                color: 'var(--mantine-color-white)',
                backgroundColor: `var(--mantine-color-${dayEvents[0].color}-filled)`,
              }}
            >
              {dayEvents.length}
            </div>
          )}
        </>
      )}
    />
  );
}
ResourcesMonthView event resize

ResourcesMonthView now supports the withEventResize prop. Events
can be resized by dragging their start or end edges, and the onEventResize callback is called with
the updated event start and end dates. Resizing snaps to whole days and preserves the event's original
time of day. Use canResizeEvent to control which events can be resized:

// Demo.tsx
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesMonthView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';

function Demo() {
  const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
  const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);

  return (
    <ResourcesMonthView
      date={date}
      onDateChange={setDate}
      resources={resources}
      events={events}
      withEventResize
      onEventResize={({ eventId, newStart, newEnd }) => {
        setEvents((current) =>
          current.map((event) =>
            event.id === eventId
              ? { ...event, start: newStart, end: newEnd }
              : event
          )
        );
      }}
      startScrollDate={dayjs().format('YYYY-MM-DD')}
    />
  );
}

// data.ts
import dayjs from 'dayjs';
import { ScheduleResourceData } from '@mantine/schedule';

const today = dayjs().format('YYYY-MM-DD');
const tomorrow = dayjs().add(1, 'day').format('YYYY-MM-DD');
const nextWeek = dayjs().add(5, 'day').format('YYYY-MM-DD');

const resources: ScheduleResourceData[] = [
  { id: 'tokyo', label: 'Meeting room: Tokyo' },
  { id: 'paris', label: 'Meeting room: Paris' },
  { id: 'new-york', label: 'Meeting room: New York' },
];

const events = [
  {
    id: 1,
    title: 'Team Standup',
    start: \`\${today} 09:00:00\`,
    end: \`\${today} 09:30:00\`,
    color: 'blue',
    resourceId: 'tokyo',
  },
  {
    id: 2,
    title: 'Sprint Planning',
    start: \`\${today} 10:00:00\`,
    end: \`\${today} 11:30:00\`,
    color: 'green',
    resourceId: 'paris',
  },
  {
    id: 3,
    title: 'Design Review',
    start: \`\${tomorrow} 13:00:00\`,
    end: \`\${tomorrow} 14:00:00\`,
    color: 'orange',
    resourceId: 'tokyo',
  },
  {
    id: 4,
    title: 'Client Call',
    start: \`\${tomorrow} 09:30:00\`,
    end: \`\${tomorrow} 10:30:00\`,
    color: 'violet',
    resourceId: 'new-york',
  },
  {
    id: 5,
    title: 'Workshop',
    start: \`\${nextWeek} 14:00:00\`,
    end: \`\${nextWeek} 16:00:00\`,
    color: 'pink',
    resourceId: 'paris',
  },
];
Schedule drag and resize intervals

Time-grid Schedule views (DayView, WeekView, ResourcesDayView, ResourcesWeekView) now support
eventDragInterval and eventResizeInterval props that set the snap step used when events are moved
and resized, independent of the intervalMinutes grid size. For example, a 30-minute grid can allow
15-minute drag and resize increments. A ghost preview shows where the event will land while dragging:

import { useState } from 'react';
import dayjs from 'dayjs';
import { DayView, ScheduleEventData } from '@mantine/schedule';

const today = dayjs().format('YYYY-MM-DD');

const initialEvents: ScheduleEventData[] = [
  {
    id: 1,
    title: 'Morning Standup',
    start: `${today} 09:00:00`,
    end: `${today} 09:30:00`,
    color: 'blue',
  },
  {
    id: 2,
    title: 'Team Meeting',
    start: `${today} 11:00:00`,
    end: `${today} 12:00:00`,
    color: 'green',
  },
  {
    id: 3,
    title: 'Code Review',
    start: `${today} 14:00:00`,
    end: `${today} 15:00:00`,
    color: 'violet',
  },
];

function Demo() {
  const [events, setEvents] = useState(initialEvents);

  const handleEventDrop = ({ eventId, newStart, newEnd }: { eventId: string | number; newStart: string; newEnd: string }) => {
    setEvents((prev) =>
      prev.map((event) =>
        event.id === eventId ? { ...event, start: newStart, end: newEnd } : event
      )
    );
  };

  return (
    <DayView
      date={new Date()}
      events={events}
      startTime="08:00:00"
      endTime="18:00:00"
      intervalMinutes={30}
      eventDragInterval={15}
      withSubHourGridLines={false}
      withEventsDragAndDrop
      onEventDrop={handleEventDrop}
    />
  );
}
import { useState } from 'react';
import dayjs from 'dayjs';
import { DayView, ScheduleEventData } from '@mantine/schedule';

const today = dayjs().format('YYYY-MM-DD');

const initialEvents: ScheduleEventData[] = [
  {
    id: 1,
    title: 'Morning Standup',
    start: `${today} 09:00:00`,
    end: `${today} 09:30:00`,
    color: 'blue',
  },
  {
    id: 2,
    title: 'Team Meeting',
    start: `${today} 11:00:00`,
    end: `${today} 12:00:00`,
    color: 'green',
  },
  {
    id: 3,
    title: 'Code Review',
    start: `${today} 14:00:00`,
    end: `${today} 15:00:00`,
    color: 'violet',
  },
];

function Demo() {
  const [events, setEvents] = useState(initialEvents);

  const handleEventResize = ({ eventId, newStart, newEnd }: { eventId: string | number; newStart: string; newEnd: string }) => {
    setEvents((prev) =>
      prev.map((event) =>
        event.id === eventId ? { ...event, start: newStart, end: newEnd } : event
      )
    );
  };

  return (
    <DayView
      date={new Date()}
      events={events}
      startTime="08:00:00"
      endTime="18:00:00"
      intervalMinutes={30}
      eventResizeInterval={15}
      withSubHourGridLines={false}
      withEventResize
      onEventResize={handleEventResize}
    />
  );
}
Dropzone react-dropzone 20

Dropzone now depends on react-dropzone 20 (previously 15). The upgrade brings several
behavior and type changes:

  • maxFiles no longer rejects the entire batch when more files are picked than the limit allows.
    Files up to the limit are now accepted and the rest are rejected. For example, picking 3 files with
    maxFiles={2} calls onDrop with the first 2 files and onReject with the third – previously all 3
    files were rejected and onDrop was called with an empty array.
  • FileWithPath type now has required path and relativePath properties, they were optional
    before. The default file aggregator always sets both values, so onDrop files can be read without
    optional chaining. If you provide a custom getFilesFromEvent that returns plain File objects,
    these properties are not set at runtime.
  • getFilesFromEvent prop now receives DropEvent | FileSystemFileHandle[] instead of DropEvent
    the File System Access API path passes file handles to the aggregator. Update the parameter type of
    custom aggregators to accept both.
  • react-dropzone 20 requires Node.js 22 or later. Mantine now requires Node.js 22 as well –
    Node.js 20 reached end of life in April 2026. This affects your development environment only,
    browser support is not changed.
Other changes
  • ColorInput now supports fullWidth prop: the dropdown matches the width of the input and the color picker inside it fills the available space.
  • FloatingWindow now supports onSizeChange, onResizeStart and onResizeEnd callbacks that mirror onPositionChange, onDragStart and onDragEnd used for dragging. Sizes passed to onSizeChange are measured after the new size has been applied, so they are already clamped by the dimensions and viewport constraints.
  • PasswordInput now supports visibilityToggleFocusable prop that puts the visibility toggle in the tab order: the button receives tabindex="0" and can be activated with Enter or Space.
  • Schedule views (DayView, WeekView, MonthView, ResourcesDayView, ResourcesWeekView) now support withInteractiveBackgroundEvents prop – background events (display: 'background') become clickable and trigger onEventClick, which makes it possible to open an edit modal for unavailability blocks and similar events.
  • use-scroll-spy hook scrollHost option now accepts a ref object in addition to a resolved HTMLElement – the hook reads ref.current internally once the element is mounted, so the scroll host does not need to exist on the first render.
  • YearView now supports withWeekendDays prop. Set withWeekendDays={false} to hide weekend days – every month grid shrinks to the remaining columns and events that fall only on hidden days are not displayed.

v9.5.2

Compare Source

  • [@mantine/hooks] use-debounced-value: Fix leading: true firing multiple times per burst and emiting a stale value (#​9119)
  • [@mantine/schedule] Fix recurring events not working with timzones (#​9112)
  • [@mantine/dates] Fix minDate used for default date in some cases (#​9117)
  • [@mantine/core] Tooltip: Fix tooltip setting NaN in top/left position style when event position values cannot be read (#​9131)
  • [@mantine/dates] TimePicker: Fix incorrect focus handling of partially filled hours field (#​9128)
  • [@mantine/core] RollingNumber: Fix incorrect copy event handling (#​9132)
  • [@mantine/core] Notification: Fix incorrect closeButtonProps type (#​9134)
  • [@mantine/code-highlight] Add support for lazy languages loading (#​9141)
  • [@mantine/code-highlight] CodeHighlight: Add prop to keep indentation of the first line of the code block (#​9140)
  • [@mantine/dates] Add missing formatting functions to MiniCalendarm DateInput and YarsList components
  • [@mantine/schedule] WeekView: Improve performance of events positioning algorithm (#​9075)
  • [@mantine/form] Add new useWatchValue hook
  • [@mantine/core] Fix Combobox-based components not working correctly with Chrome autocomplete

v9.5.1

Compare Source

  • [@mantine/tiptap] Fix controls being initially disabledbefore element is focused
  • [@mantine/tiptap] Fix source code control wrapping content with extra p tag
  • [@mantine/hooks] use-scroll-spy: Allow usage with refs (#​9025)
  • [@mantine/core] ColorInput: Add support for fullWidth prop (#​9061)
  • [@mantine/core] Checkbox: Fix incottect indeterminate aria attributes handling in Checkbox.Card (#​9095)
  • [@mantine/core] FloatingIndicator: Fix position and size calculation under scaled ancestors (#​9071)
  • [@mantine/core] Tooltip: Add interactive prop support (#​9072)
  • [@mantine/core] Cascader: Add safe area polygon support
  • [@mantine/core] PasswordInput: Add option to change whether the visibility toggle is focusable (#​9090)
  • [@mantine/charts] ScatterChart: Add option to add second y axis
  • [@mantine/schedule] YearView: Add renderDay prop support
  • [@mantine/schedule] YearView: Add option to hide weekend days
  • [@mantine/core] InputWrapper: Fix component: div triggering typescript error if passed to descriptionProps
  • [@mantine/schedule] ResourcesMonthView: Add option to resize events
  • [@mantine/core] FloatingWindow: Add support for onSizeChange and onResizeStart props (#​9085)

v9.5.0: 🤖

Compare Source

View changelog with demos on mantine.dev website

Support Mantine development

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

Migration to oxc

Mantine has migrated its linting and formatting toolchain from ESLint and Prettier
to oxcoxlint is now used
as the linter and oxfmt as the formatter. Both
tools are written in Rust and are significantly faster than their predecessors, which
makes linting and formatting the entire codebase almost instant.

The shared configuration is available as a new
oxc-config-mantine package (a replacement for the previous
eslint-config-mantine). You can use it in your own projects to follow the same
code style and conventions as Mantine.

Native level select in date pickers

DatePicker and all other date picker components (DatePickerInput,
MonthPicker, YearPicker, DateTimePicker, etc.)
now support the withNativeLevelSelect prop. When enabled, it replaces the calendar header level button
with native <select> elements, making it easy to quickly navigate to a specific month and year.

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

function Demo() {
  return <DatePicker withNativeLevelSelect yearsSelectRange={[2020, 2035]} />;
}
Timeline opposite and alternate content

Timeline Timeline.Item component now supports the opposite prop that allows
rendering content on the opposite side of the timeline. When any item has the opposite prop,
the timeline switches to a centered layout with content on both sides of the line.

import { Timeline, Text } from '@mantine/core';
import { GitBranchIcon, GitCommitIcon, GitPullRequestIcon, ChatCircleDotsIcon } from '@phosphor-icons/react';

function Demo() {
  return (
    <Timeline active={1} bulletSize={24} lineWidth={2}>
      <Timeline.Item
        bullet={<GitBranchIcon size={12} />}
        title="New branch"
        opposite={
          <Text size="sm" c="dimmed">
            2 hours ago
          </Text>
        }
      >
        <Text c="dimmed" size="sm">You&apos;ve created new branch <Text variant="link" component="span" inherit>fix-notifications</Text> from master</Text>
      </Timeline.Item>

      <Timeline.Item
        bullet={<GitCommitIcon size={12} />}
        title="Commits"
        opposite={
          <Text size="sm" c="dimmed">
            52 minutes ago
          </Text>
        }
      >
        <Text c="dimmed" size="sm">You&apos;ve pushed 23 commits to <Text variant="link" component="span" inherit>fix-notifications branch</Text></Text>
      </Timeline.Item>

      <Timeline.Item
        title="Pull request"
        bullet={<GitPullRequestIcon size={12} />}
        lineVariant="dashed"
        opposite={
          <Text size="sm" c="dimmed">
            34 minutes ago
          </Text>
        }
      >
        <Text c="dimmed" size="sm">You&apos;ve submitted a pull request <Text variant="link" component="span" inherit>Fix incorrect notification message (#&#8203;187)</Text></Text>
      </Timeline.Item>

      <Timeline.Item title="Code review" bullet={<ChatCircleDotsIcon size={12} />}>
        <Text c="dimmed" size="sm"><Text variant="link" component="span" inherit>Robert Gluesticker</Text> left a code review on your pull request</Text>
      </Timeline.Item>
    </Timeline>
  );
}

Set the alternate prop on individual Timeline.Item components to switch
the position of content and opposite:

import { Timeline, Text } from '@mantine/core';
import { GitBranchIcon, GitCommitIcon, GitPullRequestIcon, ChatCircleDotsIcon } from '@phosphor-icons/react';

function Demo() {
  return (
    <Timeline active={2} bulletSize={24} lineWidth={2}>
      <Timeline.Item
        bullet={<GitBranchIcon size={12} />}
        title="New branch"
        opposite={
          <Text size="sm" c="dimmed">
            2 hours ago
          </Text>
        }
      >
        <Text c="dimmed" size="sm">You&apos;ve created new branch <Text variant="link" component="span" inherit>fix-notifications</Text> from master</Text>
      </Timeline.Item>

      <Timeline.Item
        bullet={<GitCommitIcon size={12} />}
        title="Commits"
        opposite={
          <Text size="sm" c="dimmed">
            52 minutes ago
          </Text>
        }
        alternate
      >
        <Text c="dimmed" size="sm">You&apos;ve pushed 23 commits to <Text variant="link" component="span" inherit>fix-notifications branch</Text></Text>
      </Timeline.Item>

      <Timeline.Item
        title="Pull request"
        bullet={<GitPullRequestIcon size={12} />}
        lineVariant="dashed"
        opposite={
          <Text size="sm" c="dimmed">
            34 minutes ago
          </Text>
        }
      >
        <Text c="dimmed" size="sm">You&apos;ve submitted a pull request <Text variant="link" component="span" inherit>Fix incorrect notification message (#&#8203;187)</Text></Text>
      </Timeline.Item>

      <Timeline.Item
        title="Code review"
        bullet={<ChatCircleDotsIcon size={12} />}
        opposite={
          <Text size="sm" c="dimmed">
            12 minutes ago
          </Text>
        }
        alternate
      >
        <Text c="dimmed" size="sm"><Text variant="link" component="span" inherit>Robert Gluesticker</Text> left a code review on your pull request</Text>
      </Timeline.Item>
    </Timeline>
  );
}
FloatingWindow resize handle

FloatingWindow now supports a ResizeHandle compound component
that allows users to resize the floating window by dragging a handle element.
Set the dimensions prop on FloatingWindow to control resize constraints for both
width (initialWidth, minWidth, maxWidth) and height (initialHeight, minHeight, maxHeight).

The resize handle is fully accessible – it supports keyboard interaction with
Arrow Left/Arrow Right keys for width, Arrow Up/Arrow Down for height (10px steps),
and Home/End keys (jump to min/max size).

import { NotchesIcon } from '@phosphor-icons/react';
import { Button, CloseButton, FloatingWindow, Group, Text } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';

function Demo() {
  const [visible, handlers] = useDisclosure();

  return (
    <>
      <Button onClick={handlers.toggle} variant="default">
        {visible ? 'Hide' : 'Show'} floating window
      </Button>

      {visible && (
        <FloatingWindow
          withBorder
          constrainOffset={40}
          dimensions={{
            initialWidth: 260,
            maxWidth: 500,
            minWidth: 180,
            initialHeight: 260,
            maxHeight: 400,
            minHeight: 220,
          }}
          dragHandleSelector=".drag-handle"
          excludeDragHandleSelector="button"
          initialPosition={{ top: 300, left: 60 }}
          style={{ overflow: 'hidden' }}
        >
          <Group
            justify="space-between"
            px="md"
            py="sm"
            className="drag-handle"
            style={{ cursor: 'move' }}
          >
            <Text fw={500} fz="sm">
              Resize demo
            </Text>
            <CloseButton onClick={handlers.close} />
          </Group>
          <Text fz="sm" px="md" pb="sm">
            Drag the grip icon in the bottom-right corner to resize.
            Use Arrow keys when the handle is focused:
            Left/Right for width, Up/Down for height.
          </Text>
          <FloatingWindow.ResizeHandle
            aria-label="Resize floating window"
            style={{
              position: 'absolute',
              right: 0,
              bottom: 0,
              width: 20,
              height: 20,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              cursor: 'nwse-resize',
            }}
          >
            <NotchesIcon size={14} style={{ opacity: 0.5 }} />
          </FloatingWindow.ResizeHandle>
        </FloatingWindow>
      )}
    </>
  );
}
Cascader component

New Cascader component allows selecting a value from hierarchical data
by drilling down through cascading columns. Picking an option in one column reveals its
children in a new column to the right, and the value is an ordered path from the root option
to the selected node. It supports changeOnSelect, hover expand trigger, search, a flat list
layout for mobile, and full keyboard navigation.

import { Cascader, useMatches } from '@mantine/core';
import { data } from './data';

function Demo() {
  // Switch to a flat list on small screens
  const withColumns = useMatches({ base: false, sm: true });
  return (
    <Cascader
      withColumns={withColumns}
      label="Location"
      placeholder="Pick location"
      data={data}
    />
  );
}
SunburstChart component

New SunburstChart component displays hierarchical data
as concentric rings, similar to a treemap plotted in polar coordinates.

// Demo.tsx
import { SunburstChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return <SunburstChart data={data} />;
}

// data.ts
export const data = [
  { name: 'Analytics', value: 100, color: 'pink.6' },
  {
    name: 'DevOps',
    color: 'grape.6',
    children: [
      { name: 'Docker', value: 80 },
      { name: 'Kubernetes', value: 50 },
    ],
  },
  {
    name: 'Backend',
    color: 'teal.6',
    children: [
      { name: 'Node', value: 150 },
      {
        name: 'Python',
        children: [
          { name: 'Django', value: 110 },
          { name: 'FastAPI', value: 60 },
        ],
      },
      { name: 'Go', value: 50 },
    ],
  },
  {
    name: 'Frontend',
    color: 'blue.6',
    children: [
      {
        name: 'React',
        children: [
          {
            name: 'Frameworks',
            children: [
              { name: 'Next.js', value: 150 },
              { name: 'Remix', value: 40 },
            ],
          },
          { name: 'CRA', value: 20 },
        ],
      },
      { name: 'Vue', value: 90 },
      { name: 'Svelte', value: 30 },
    ],
  },
];
BulletChart component

New BulletChart component displays a single measure against
a qualitative range, useful for comparing a primary value (such as revenue) against
a target and qualitative thresholds like poor, average, and good.

// Demo.tsx
import { BulletChart } from '@mantine/charts';
import { ranges } from './data';

function Demo() {
  return (
    <BulletChart
      value={230000}
      target={150000}
      ranges={ranges}
      valueFormatter={(value) => `${(value / 1000).toFixed(0)}k`}
    />
  );
}

// data.ts
export const ranges = ${JSON.stringify(ranges, null, 2)};
Charts keyboard navigation

All @​mantine/charts components now expose the
accessibilityLayer prop (true by default) that makes charts navigable with the keyboard.
The chart surface is focusable and displays the Mantine focus ring; once focused, the arrow keys
move the active tooltip point-by-point and Enter toggles the tooltip, so users who do not
use a mouse can read the underlying values. The prop is supported by AreaChart, BarChart,
LineChart, CompositeChart, ScatterChart, BubbleChart, PieChart, DonutChart, RadarChart,
RadialBarChart and FunnelChart components.

Charts brush

AreaChart, BarChart, LineChart
and CompositeChart now support the withBrush prop that displays a
brush (range selector) under the chart. Drag the brush handles to zoom into a subset of the data.
Use the brushProps prop to customize the underlying recharts Brush, or render the new
themed ChartBrush component as a child of the chart for full control.

// Demo.tsx
import { AreaChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <AreaChart
      h={300}
      data={data}
      dataKey="date"
      withBrush
      series={[
        { name: 'Apples', color: 'indigo.6' },
        { name: 'Oranges', color: 'blue.6' },
      ]}
    />
  );
}

// data.ts
export const data = [
  { date: 'Mar 1', Apples:

>  **Note**
> 
> PR body was truncated to here.


</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

 **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sarod/book-scanner).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDAuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjQ5LjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

@renovate renovate Bot assigned sarod Mar 31, 2026
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from e8c32d7 to 4a56161 Compare April 13, 2026 08:59
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 7f6ce36 to c1a65a7 Compare April 21, 2026 20:40
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 3cd554d to 25a092d Compare April 29, 2026 11:06
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 918284f to 913f29a Compare May 11, 2026 16:51
@renovate renovate Bot changed the title fix(deps): update mantine monorepo to v9 (major) fix(deps): update mantine monorepo to v9 May 12, 2026
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 58d281b to 69e2435 Compare May 18, 2026 15:07
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 781c665 to 9e07005 Compare May 28, 2026 15:05
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from f40c2e5 to 97a6965 Compare June 11, 2026 21:13
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from f8e842f to 410bc4d Compare June 28, 2026 13:03
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 7376ca4 to 2494712 Compare July 5, 2026 05:27
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch from 2494712 to ad06fcb Compare July 12, 2026 12:30
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 3d8a536 to 6fb4927 Compare July 30, 2026 17:08
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch from 6fb4927 to 696889b Compare August 11, 2026 21:44
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 7f8be76 to 25b1651 Compare August 26, 2026 17:15
@renovate
renovate Bot force-pushed the renovate/major-mantine-monorepo branch from 25b1651 to 3c6c721 Compare September 2, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant