Skip to content

fix(deps): update mantine monorepo to v9 (major)#233

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

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

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate bot commented Sep 18, 2023

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@mantine/core (source) 6.0.229.0.0 age confidence
@mantine/hooks (source) 6.0.229.0.0 age confidence

Release Notes

mantinedev/mantine (@​mantine/core)

v9.0.0: 🤩

Compare Source

View changelog with demos on mantine.dev website

Migration guide

This changelog covers breaking changes and new features in Mantine 9.0.
To migrate your application to Mantine 9.0, follow 8.x → 9.x migration guide.

Peer dependencies requirements updates

Starting from Mantine 9.0, the following dependencies are required:

  • React 19.2+ for all @mantine/* packages
  • Tiptap 3+ for @mantine/tiptap (migration guide)
  • Recharts 3+ for @mantine/charts (no migration required)

New @​mantine/schedule package

New @mantine/schedule package provides a complete set of
calendar scheduling components for React applications. It includes multiple view levels,
drag-and-drop event management, and extensive customization options.

Schedule

Schedule is a unified container component that combines all views with built-in navigation and view switching. Drag events to reschedule them:

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

const today = dayjs().format('YYYY-MM-DD');
const tomorrow = dayjs().add(1, 'day').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} 10:00:00`,
    end: `${today} 11:30:00`,
    color: 'green',
  },
  {
    id: 3,
    title: 'Lunch Break',
    start: `${today} 12:00:00`,
    end: `${today} 13:00:00`,
    color: 'orange',
  },
  {
    id: 4,
    title: 'Code Review',
    start: `${tomorrow} 14:00:00`,
    end: `${tomorrow} 15:00:00`,
    color: 'violet',
  },
  {
    id: 5,
    title: 'Client Call',
    start: `${tomorrow} 15:30:00`,
    end: `${tomorrow} 16:30:00`,
    color: 'cyan',
  },
  {
    id: 6,
    title: 'All Day Conference',
    start: `${today} 00:00:00`,
    end: dayjs(today).add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    color: 'red',
  },
];

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 (
    <Schedule
      events={events}
      withEventsDragAndDrop
      onEventDrop={handleEventDrop}
    />
  );
}
DayView

DayView displays a single day with configurable time slots, all-day event section, current time indicator, and business hours highlighting. Drag events to reschedule them:

import { useState } from 'react';
import dayjs from 'dayjs';
import { DayView, ScheduleEventData } from '@&#8203;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"
      withEventsDragAndDrop
      onEventDrop={handleEventDrop}
    />
  );
}
WeekView

WeekView shows a weekly calendar grid with time slots, week numbers, weekend day toggling, and multi-day event spanning. Drag events across days and time slots:

import { useState } from 'react';
import dayjs from 'dayjs';
import { WeekView, ScheduleEventData } from '@&#8203;mantine/schedule';

const today = dayjs().format('YYYY-MM-DD');
const tomorrow = dayjs().add(1, 'day').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: `${tomorrow} 11:00:00`,
    end: `${tomorrow} 12:00:00`,
    color: 'green',
  },
  {
    id: 3,
    title: 'Code Review',
    start: `${today} 14:00:00`,
    end: `${today} 15:00:00`,
    color: 'violet',
  },
  {
    id: 4,
    title: 'Company Holiday',
    start: dayjs(getStartOfWeek({ date: today, firstDayOfWeek: 1 })).format('YYYY-MM-DD HH:mm:ss'),
    end: dayjs(getStartOfWeek({ date: today, firstDayOfWeek: 1 }))
      .add(2, 'day')
      .format('YYYY-MM-DD HH:mm:ss'),
    color: 'red',
  },
  {
    id: 5,
    title: 'Release Day',
    start: dayjs(getStartOfWeek({ date: today, firstDayOfWeek: 1 })).format('YYYY-MM-DD HH:mm:ss'),
    end: dayjs(getStartOfWeek({ date: today, firstDayOfWeek: 1 }))
      .add(2, 'day')
      .format('YYYY-MM-DD HH:mm:ss'),
    color: 'orange',
  },
];

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 (
    <WeekView
      date={new Date()}
      events={events}
      startTime="08:00:00"
      endTime="18:00:00"
      withEventsDragAndDrop
      onEventDrop={handleEventDrop}
    />
  );
}
MonthView

MonthView displays a monthly calendar grid with event overflow handling, outside days display, and week numbers. Drag events to different days:

import { useState } from 'react';
import dayjs from 'dayjs';
import { MonthView, ScheduleEventData } from '@&#8203;mantine/schedule';

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

const initialEvents: ScheduleEventData[] = [
  {
    id: 1,
    title: 'Team Meeting',
    start: `${today} 09:00:00`,
    end: `${today} 10:30:00`,
    color: 'blue',
  },
  {
    id: 2,
    title: 'Project Deadline',
    start: dayjs().add(5, 'day').format('YYYY-MM-DD 00:00:00'),
    end: dayjs().add(6, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    color: 'red',
  },
];

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 <MonthView date={new Date()} events={events} withEventsDragAndDrop onEventDrop={handleEventDrop} />;
}
YearView

YearView provides a 12-month year overview organized by quarters with day-level event indicators:

// Demo.tsx
import dayjs from 'dayjs';
import { useState } from 'react';
import { YearView } from '@&#8203;mantine/schedule';
import { events } from './data';

function Demo() {
  const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));

  return (
    <YearView
      date={date}
      onDateChange={setDate}
      events={events}
    />
  );
}

// data.ts
import dayjs from 'dayjs';

const thisYear = dayjs().format('YYYY');

const events = [
  {
    id: 1,
    title: 'New Year',
    start: \\\`\\\${thisYear}-01-01 00:00:00\\\`,
    end: dayjs(\\\`\\\${thisYear}-01-01\\\`).add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    color: 'blue',
  },
  {
    id: 2,
    title: 'Spring Event',
    start: \\\`\\\${thisYear}-03-15 00:00:00\\\`,
    end: dayjs(\\\`\\\${thisYear}-03-15\\\`).add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    color: 'green',
  },
];
MobileMonthView

MobileMonthView is a mobile-optimized month view with event details panel for the selected day:

// Demo.tsx
import dayjs from 'dayjs';
import { useState } from 'react';
import { MobileMonthView } from '@&#8203;mantine/schedule';
import { events } from './data';

function Demo() {
  const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
  const [selectedDate, setSelectedDate] = useState<string | null>(dayjs().format('YYYY-MM-DD'));

  return (
    <MobileMonthView
      date={date}
      onDateChange={setDate}
      selectedDate={selectedDate}
      onSelectedDateChange={setSelectedDate}
      events={regularEvents}
    />
  );
}

// data.ts
import dayjs from 'dayjs';

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

export const events = [
  {
    id: 1,
    title: 'Team Meeting',
    start: \`\${thisMonth}-05 09:00:00\`,
    end: \`\${thisMonth}-05 10:00:00\`,
    color: 'blue',
  },
  {
    id: 2,
    title: 'Project Review',
    start: \`\${thisMonth}-05 14:00:00\`,
    end: \`\${thisMonth}-05 15:30:00\`,
    color: 'green',
  },
  {
    id: 3,
    title: 'Conference',
    start: \`\${thisMonth}-10 00:00:00\`,
    end: \`\${thisMonth}-12 00:00:00\`,
    color: 'violet',
  },
  // ... more events
];

To get started, follow the getting started guide.

Collapse horizontal orientation

Collapse component now supports horizontal orientation:

import { Button, Collapse, Stack, Typography } from '@&#8203;mantine/core';
import { useDisclosure } from '@&#8203;mantine/hooks';

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

  return (
    <Stack h={240} align="flex-start">
      <Button onClick={handlers.toggle} w="fit-content">
        {expanded ? 'Collapse' : 'Expand'}
      </Button>

      <Collapse expanded={expanded} orientation="horizontal">
        <Typography bg="var(--mantine-color-blue-light)" p="xs" bdrs="md" w={200}>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
          ut labore et dolore magna aliqua.
        </Typography>
      </Collapse>
    </Stack>
  );
}

use-collapse and use-horizontal-collapse hooks

New use-collapse hook is the hook version of Collapse component.
It allows animation of height from 0 to auto and vice versa.

import { Button, Typography } from '@&#8203;mantine/core';
import { useCollapse, useDisclosure } from '@&#8203;mantine/hooks';

function Demo() {
  const [expanded, handlers] = useDisclosure(false);
  const getCollapseProps = useCollapse({ expanded });

  return (
    <>
      <Button onClick={handlers.toggle} mb="md">
        {expanded ? 'Collapse' : 'Expand'}
      </Button>

      <div {...getCollapseProps()}>
        <Typography bg="var(--mantine-color-blue-light)" p="xs" bdrs="md">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
          ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
          ullamco laboris nisi ut aliquip ex ea commodo consequat.
        </Typography>
      </div>
    </>
  );
}

use-horizontal-collapse works the same way as use-collapse but animates width instead of height:

import { Button, Stack, Typography } from '@&#8203;mantine/core';
import { useDisclosure, useHorizontalCollapse } from '@&#8203;mantine/hooks';

function Demo() {
  const [expanded, handlers] = useDisclosure(false);
  const { getCollapseProps } = useHorizontalCollapse({ expanded });

  return (
    <Stack h={240}>
      <Button onClick={handlers.toggle} w="fit-content">
        {expanded ? 'Collapse' : 'Expand'}
      </Button>

      <div {...getCollapseProps({ style: { width: 200 } })}>
        <Typography bg="var(--mantine-color-blue-light)" p="xs" bdrs="md" w={200}>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
          ut labore et dolore magna aliqua.
        </Typography>
      </div>
    </Stack>
  );
}

use-floating-window hook

New use-floating-window hook allows creating floating draggable
elements:

import { Button, CloseButton, Group, Paper, Portal, Text } from '@&#8203;mantine/core';
import { useDisclosure, useFloatingWindow } from '@&#8203;mantine/hooks';

function Demo() {
  const [visible, handlers] = useDisclosure();
  const floatingWindow = useFloatingWindow({
    constrainToViewport: true,
    constrainOffset: 20,
    excludeDragHandleSelector: 'button',
    initialPosition: { top: 300, left: 20 },
  });

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

      {visible && (
        <Portal>
          <Paper
            w={280}
            p="md"
            withBorder
            pos="fixed"
            style={{ cursor: 'move', transition: 'box-shadow 70ms ease', zIndex: 400 }}
            shadow={floatingWindow.isDragging ? 'md' : undefined}
            ref={floatingWindow.ref}
          >
            <Group justify="space-between" mb="md">
              <Text>Usage demo</Text>
              <CloseButton onClick={handlers.close} />
            </Group>
            <Text fz="sm">This is a floating window. You can drag it around.</Text>
          </Paper>
        </Portal>
      )}
    </>
  );
}

FloatingWindow component

FloatingWindow provides component API for use-floating-window hook:

import { Button, CloseButton, FloatingWindow, Group, Text } from '@&#8203;mantine/core';
import { useDisclosure } from '@&#8203;mantine/hooks';

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

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

      {visible && (
        <FloatingWindow
          w={280}
          p="md"
          withBorder
          excludeDragHandleSelector="button"
          initialPosition={{ top: 300, left: 20 }}
          style={{ cursor: 'move' }}
        >
          <Group justify="space-between" mb="md">
            <Text>Usage demo</Text>
            <CloseButton onClick={handlers.close} />
          </Group>
          <Text fz="sm">This is a floating window. You can drag it around.</Text>
        </FloatingWindow>
      )}
    </>
  );
}

OverflowList component

New OverflowList component displays list of items and collapses the overflowing items into a single element:

// OverflowListDemo.tsx
import { Badge, OverflowList } from '@&#8203;mantine/core';
import { data } from './data';

function Demo() {
  return (
    <div style={{ resize: 'horizontal', overflow: 'auto', maxWidth: '100%' }}>
      <OverflowList
        data={data}
        gap={4}
        renderOverflow={(items) => <Badge>+{items.length} more</Badge>}
        renderItem={(item, index) => <Badge key={index}>{item}</Badge>}
      />
    </div>
  );
}

// data.ts
export const data = [
  'Apple',
  'Banana',
  'Cherry',
  'Date',
  'Elderberry',
  'Fig',
  'Grape',
  'Honeydew',
  'Indian Fig',
  'Jackfruit',
  'Kiwi',
  'Lemon',
  'Mango',
  'Nectarine',
  'Orange',
  'Papaya',
];

Marquee component

New Marquee component creates continuous scrolling animation for content:

import { Marquee } from '@&#8203;mantine/core';
import { MantineLogo } from '@&#8203;mantinex/mantine-logo';

function Demo() {
  return (
    <Marquee gap="lg">
      <MantineLogo width={80} type="full" color="blue" />
      <MantineLogo width={80} type="full" color="cyan" />
      <MantineLogo width={80} type="full" color="teal" />
      <MantineLogo width={80} type="full" color="green" />
      <MantineLogo width={80} type="full" color="lime" />
      <MantineLogo width={80} type="full" color="yellow" />
      <MantineLogo width={80} type="full" color="orange" />
      <MantineLogo width={80} type="full" color="red" />
    </Marquee>
  );
}

Scroller component

New Scroller component displays horizontally scrollable content with navigation controls.
It supports native scrolling via trackpad, shift + mouse wheel, touch gestures, and mouse drag:

import { Badge, Group, Scroller } from '@&#8203;mantine/core';

function Demo() {
  return (
    <Scroller>
      <Group gap="xs" wrap="nowrap">
        {Array.from({ length: 20 }).map((_, index) => (
          <Badge key={index} variant="light" size="lg">
            Badge {index + 1}
          </Badge>
        ))}
      </Group>
    </Scroller>
  );
}

use-scroller hook

New use-scroller hook provides logic for creating custom scrollable containers with navigation controls:

import { Box, Button, Group } from '@&#8203;mantine/core';
import { useScroller } from '@&#8203;mantine/hooks';

function Demo() {
  const scroller = useScroller();

  return (
    <Box>
      <Group mb="md">
        <Button
          onClick={scroller.scrollStart}
          disabled={!scroller.canScrollStart}
          variant="default"
          size="xs"
        >
          ← Scroll left
        </Button>
        <Button
          onClick={scroller.scrollEnd}
          disabled={!scroller.canScrollEnd}
          variant="default"
          size="xs"
        >
          Scroll right →
        </Button>
      </Group>

      <div
        ref={scroller.ref}
        {...scroller.dragHandlers}
        style={{
          overflow: 'auto',
          cursor: scroller.isDragging ? 'grabbing' : 'grab',
        }}
      >
        <Group wrap="nowrap" gap="md">
          {Array.from({ length: 20 }).map((_, index) => (
            <Box
              key={index}
              style={{
                minWidth: 100,
                height: 80,
                backgroundColor: 'var(--mantine-color-blue-filled)',
                borderRadius: 'var(--mantine-radius-md)',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                color: 'white',
                fontWeight: 500,
              }}
            >
              {index + 1}
            </Box>
          ))}
        </Group>
      </div>
    </Box>
  );
}

BarsList component

New BarsList component displays a list of horizontal bars with names and values.
It supports custom colors, auto contrast, value formatting, and custom bar rendering:

// Demo.tsx
import { BarsList } from '@&#8203;mantine/charts';
import { data } from './data';

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

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

Card horizontal orientation

Card component now supports horizontal orientation:

import { Box, Card, Group, RingProgress, Text } from '@&#8203;mantine/core';

const completed = 1887;
const total = 2334;
const stats = [
  { value: 447, label: 'Remaining' },
  { value: 76, label: 'In progress' },
];

function Demo() {
  const items = stats.map((stat) => (
    <div key={stat.label}>
      <Text>{stat.value}</Text>
      <Text size="xs" c="dimmed">
        {stat.label}
      </Text>
    </div>
  ));

  return (
    <Card padding="sm" withBorder orientation="horizontal">
      <Card.Section inheritPadding px="xs" withBorder>
        <RingProgress
          roundCaps
          thickness={6}
          size={150}
          sections={[{ value: (completed / total) * 100, color: 'blue' }]}
          label={
            <div>
              <Text ta="center" fz="lg">
                {((completed / total) * 100).toFixed(0)}%
              </Text>
              <Text ta="center" fz="xs" c="dimmed">
                Completed
              </Text>
            </div>
          }
        />
      </Card.Section>

      <Card.Section inheritPadding px="md">
        <Text fz="xl">Project tasks</Text>
        <Box mt="xs">
          <Text>1887</Text>
          <Text fz="xs" c="dimmed">
            Completed
          </Text>
        </Box>

        <Group mt="sm">{items}</Group>
      </Card.Section>
    </Card>
  );
}

Checkbox.Group and Switch.Group maxSelectedValues

Checkbox.Group and Switch.Group now support maxSelectedValues prop to limit the number of selected values.
When the limit is reached, the remaining controls are disabled and cannot be selected.

import { Checkbox, Group } from '@&#8203;mantine/core';

function Demo() {
  return (
    <Checkbox.Group defaultValue={['react']} maxSelectedValues={2}>
      <Group>
        <Checkbox value="react" label="React" />
        <Checkbox value="svelte" label="Svelte" />
        <Checkbox value="ng" label="Angular" />
        <Checkbox value="vue" label="Vue" />
      </Group>
    </Checkbox.Group>
  );
}

Inputs loading state

All Mantine input components based on Input component now support loading prop.

Set loading prop to display a loading indicator. By default, the loader is displayed on the right side of the input.
You can change the position with the loadingPosition prop to 'left' or 'right'. This is useful for async operations like API calls, searches, or validations:

import { TextInput } from '@&#8203;mantine/core';

function Demo() {
  return <TextInput placeholder="Your email" loading />;
}

renderPill in MultiSelect and TagsInput

MultiSelect and TagsInput components now support renderPill prop to customize pill rendering:

import { MultiSelect, Pill, Avatar } from '@&#8203;mantine/core';

const users = [
  { value: 'Emily Johnson', label: 'Emily Johnson', image: 'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-7.png' },
  { value: 'Ava Rodriguez', label: 'Ava Rodriguez', image: 'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-8.png' },
  { value: 'Olivia Chen', label: 'Olivia Chen', image: 'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-4.png' },
  { value: 'Ethan Barnes', label: 'Ethan Barnes', image: 'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-1.png' },
  { value: 'Mason Taylor', label: 'Mason Taylor', image: 'https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-2.png' },
];

const usersMap = new Map(users.map((user) => [user.value.toString(), user]));

function Demo() {
  return (
    <MultiSelect
      data={users}
      label="Candidates"
      placeholder="Select candidates"
      defaultValue={['Emily Johnson', 'Ava Rodriguez']}
      renderPill={({ option, onRemove }) => {
        const user = usersMap.get(option?.value.toString());
        return (
          <Pill withRemoveButton onRemove={onRemove}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Avatar src={user?.image} size={16} />
              {option?.label}
            </div>
          </Pill>
        );
      }}
    />
  );
}

Clear section mode

All clearable input components now support clearSectionMode prop that determines how the clear button and rightSection are rendered:

  • 'both' (default) – render both the clear button and rightSection
  • 'rightSection' – render only the user-supplied rightSection, ignore clear button
  • 'clear' – render only the clear button, ignore rightSection

This prop is supported by Select, Autocomplete,
MultiSelect, TagsInput, FileInput,
DateInput, DatePickerInput,
MonthPickerInput, YearPickerInput,
TimePicker, and DateTimePicker.

import { CaretDownIcon } from '@&#8203;phosphor-icons/react';
import { Stack } from '@&#8203;mantine/core';
import { DatePickerInput } from '@&#8203;mantine/dates';

function Demo() {
  return (
    <Stack>
      <DatePickerInput
        label="clearSectionMode='both' (default)"
        placeholder="Pick date"
        defaultValue={new Date()}
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="both"
      />

      <DatePickerInput
        label="clearSectionMode='rightSection'"
        placeholder="Pick date"
        defaultValue={new Date()}
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="rightSection"
      />

      <DatePickerInput
        label="clearSectionMode='clear'"
        placeholder="Pick date"
        defaultValue={new Date()}
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="clear"
      />
    </Stack>
  );
}

use-form async validation

use-form validation rules can now be async – return a Promise that resolves to an
error message or null. When all rules are synchronous, form.validate(), form.validateField() and
form.isValid() return their results directly (not wrapped in a Promise). When any rule is async,
these methods return promises instead. TypeScript infers the correct return type based on your
validation rules, so you get precise types without manual annotations.

The form.validating property is true while any async validation is in progress, and
form.isValidating(path) checks individual fields. The validating state is never set for
forms with only synchronous rules.

Each rule receives an AbortSignal as the fourth argument. The signal is aborted when a newer
validation supersedes the current one, which you can use to cancel in-flight HTTP requests.

import { Button, Group, Loader, TextInput } from '@&#8203;mantine/core';
import { isEmail, useForm } from '@&#8203;mantine/form';

// Simulates an async API call to check if the username is available
function checkUsernameAvailability(username: string, signal?: AbortSignal): Promise<string | null> {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      const taken = ['admin', 'user', 'test', 'mantine'];
      resolve(taken.includes(username.toLowerCase()) ? 'Username is already taken' : null);
    }, 800);

    signal?.addEventListener('abort', () => {
      clearTimeout(timer);
      reject(new DOMException('Aborted', 'AbortError'));
    });
  });
}

function Demo() {
  const form = useForm({
    mode: 'uncontrolled',
    initialValues: { username: '', email: '' },
    validate: {
      username: async (value, _values, _path, signal) => {
        if (value.trim().length < 3) {
          return 'Username must be at least 3 characters';
        }
        return checkUsernameAvailability(value, signal);
      },
      email: isEmail('Invalid email'),
    },
  });

  return (
    <form onSubmit={form.onSubmit((values) => console.log(values))}>
      <TextInput
        withAsterisk
        label="Username"
        placeholder="Pick a username"
        key={form.key('username')}
        disabled={form.submitting}
        rightSection={form.validating ? <Loader size={16} /> : null}
        {...form.getInputProps('username')}
      />

      <TextInput
        withAsterisk
        mt="md"
        label="Email"
        placeholder="your@email.com"
        key={form.key('email')}
        disabled={form.submitting}
        {...form.getInputProps('email')}
      />

      <Group justify="flex-end" mt="md">
        <Button type="submit" loading={form.submitting}>
          Submit
        </Button>
      </Group>
    </form>
  );
}

When using async validation with validateInputOnChange, set validateDebounce to avoid
firing an API call on every keystroke:

import { Button, Group, Loader, TextInput } from '@&#8203;mantine/core';
import { useForm, isEmail } from '@&#8203;mantine/form';

// Simulates an async API call to check if the username is available
function checkUsernameAvailability(username: string, signal?: AbortSignal): Promise<string | null> {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      const taken = ['admin', 'user', 'test', 'mantine'];
      resolve(taken.includes(username.toLowerCase()) ? 'Username is already taken' : null);
    }, 800);

    signal?.addEventListener('abort', () => {
      clearTimeout(timer);
      reject(new DOMException('Aborted', 'AbortError'));
    });
  });
}

function Demo() {
  const form = useForm({
    mode: 'uncontrolled',
    initialValues: { username: '', email: '' },

    // Debounce async validation by 500ms – prevents firing
    // an API call on every keystroke
    validateDebounce: 500,
    validateInputOnChange: ['username'],

    validate: {
      username: async (value, _values, _path, signal) => {
        if (value.trim().length < 3) {
          return 'Username must be at least 3 characters';
        }
        return checkUsernameAvailability(value, signal);
      },
      email: isEmail('Invalid email'),
    },
  });

  return (
    <form onSubmit={form.onSubmit((values) => console.log(values))}>
      <TextInput
        withAsterisk
        label="Username"
        description="Try: admin, user, test, mantine"
        placeholder="Pick a username"
        key={form.key('username')}
        disabled={form.submitting}
        rightSection={form.isValidating('username') ? <Loader size={16} /> : null}
        {...form.getInputProps('username')}
      />

      <TextInput
        withAsterisk
        mt="md"
        label="Email"
        placeholder="your@email.com"
        key={form.key('email')}
        disabled={form.submitting}
        {...form.getInputProps('email')}
      />

      <Group justify="flex-end" mt="md">
        <Button type="submit" loading={form.submitting}>
          Submit
        </Button>
      </Group>
    </form>
  );
}

use-form TransformedValues type argument

use-form now supports passing second type argument TransformedValues to define the type of
transformed values returned by form.getTransformedValues and form.onSubmit:

import { useForm } from '@&#8203;mantine/form';

interface FormValues {
  name: string;
  locationId: string;
}

interface TransformedValues {
  name: string;
  locationId: number;
}

function Demo() {
  const form = useForm<FormValues, TransformedValues>({
    mode: 'uncontrolled',
    initialValues: {
      name: '',
      locationId: '2',
    },

    transformValues: (values) => ({
      ...values,
      locationId: Number(values.locationId),
    }),
  });
}

Generic components

SegmentedControl, Select, MultiSelect,
Chip.Group, Switch.Group, Checkbox.Group and Radio.Group
now support generic value type. You can pass primitive values (numbers, strings, booleans, bigint)
as the type argument. The generic type is used for value, defaultValue, onChange and other props.

For example, generic type can now be used with SegmentedControl
to specify string union:

import { SegmentedControl } from '@&#8203;mantine/core';

function Demo() {
  return (
    <SegmentedControl<'orange' | 'grape' | 'apple'>
      data={[
        { value: 'orange', label: 'Orange' },
        { value: 'grape', label: 'Grape' },
        { value: 'apple', label: 'Apple' },
      ]}
    />
  );
}

Combobox virtualization

Combobox component now supports virtualization
with the useVirtualizedCombobox hook. The hook does not depend on any specific virtualization library.
The recommended option is @​tanstack/react-virtual.

Example of implementation with useVirtualizedCombobox and @​tanstack/react-virtual:

import { useState } from 'react';
import { useVirtualizer } from '@&#8203;tanstack/react-virtual';
import { Combobox, Input, InputBase, ScrollArea, useVirtualizedCombobox } from '@&#8203;mantine/core';

const ITEM_HEIGHT = 36;

const largeData = Array(10000)
  .fill(0)
  .map((_, index) => ({
    value: `value-${index}`,
    label: `Label ${index}`,
    id: `item-${index}`,
    disabled: false,
  }));

function Demo() {
  const [opened, setOpened] = useState(false);
  const [selectedOptionIndex, setSelectedOptionIndex] = useState(-1);
  const [activeOptionIndex, setActiveOptionIndex] = useState(-1);
  const [value, setValue] = useState('');
  const [scrollParent, setScrollParent] = useState<HTMLDivElement | null>(null);

  const virtualizer = useVirtualizer({
    count: largeData.length,
    getScrollElement: () => scrollParent,
    estimateSize: () => ITEM_HEIGHT,
    overscan: 5,
  });

  const combobox = useVirtualizedCombobox({
    opened,
    onOpenedChange: setOpened,
    onDropdownOpen: () => {
      if (activeOptionIndex !== -1) {
        setSelectedOptionIndex(activeOptionIndex);
        requestAnimationFrame(() => {
          virtualizer.scrollToIndex(activeOptionIndex, { align: 'auto' });
        });
      }
    },
    isOptionDisabled: (index) => largeData[index].disabled,
    totalOptionsCount: largeData.length,
    getOptionId: (index) => largeData[index].id,
    selectedOptionIndex,
    activeOptionIndex,
    setSelectedOptionIndex: (index) => {
      setSelectedOptionIndex(index);
      if (index !== -1) {
        virtualizer.scrollToIndex(index, { align: 'auto' });
      }
    },
    onSelectedOptionSubmit: onOptionSubmit,
  });

  function onOptionSubmit(index: number) {
    const option = largeData[index];
    setValue(option.value);
    setActiveOptionIndex(index);
    combobox.closeDropdown();
    combobox.resetSelectedOption();
  }

  return (
    <Combobox store={combobox} resetSelectionOnOptionHover={false} keepMounted>
      <Combobox.Target>
        <InputBase component="button" onClick={() => combobox.toggleDropdown()} pointer>
          {value || <Input.Placeholder>Pick a value</Input.Placeholder>}
        </InputBase>
      </Combobox.Target>
      <Combobox.Dropdown>
        <Combobox.Options>
          <ScrollArea.Autosize
            mah={220}
            type="scroll"
            scrollbarSize={4}
            viewportRef={setScrollParent}
            onMouseDown={(event) => event.preventDefault()}
          >
            <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
              {virtualizer.getVirtualItems().map((virtualItem) => {
                const item = largeData[virtualItem.index];
                return (
                  <Combobox.Option
                    value={item.value}
                    key={item.value}
                    active={virtualItem.index === activeOptionIndex}
                    selected={virtualItem.index === selectedOptionIndex}
                    onClick={() => onOptionSubmit(virtualItem.index)}
                    style={{
                      position: 'absolute',
                      top: 0,
                      left: 0,
                      width: '100%',
                      height: virtualItem.size,
                      transform: `translateY(${virtualItem.start}px)`,
                    }}
                  >
                    {item.label}
                  </Combobox.Option>
                );
              })}
            </div>
          </ScrollArea.Autosize>
        </Combobox.Options>
      </Combobox.Dropdown>
    </Combobox>
  );
}

You can find more virtualization examples on the Combobox examples page.

Highlight per-term colors

Highlight component now supports custom colors for individual highlight terms.
You can provide an array of objects with text and color properties to assign different colors
to different highlighted terms:

import { Highlight } from '@&#8203;mantine/core';

function Demo() {
  return (
    <Highlight
      highlight={[
        { text: 'error', color: 'red' },
        { text: 'warning', color: 'yellow' },
        { text: 'success', color: 'green' },
      ]}
    >
      Error: Invalid input. Warning: Check this field. Success: All tests passed.
    </Highlight>
  );
}

Highlight whole-word matching

Highlight component now supports wholeWord prop to match only complete words.
When enabled, 'the' will not match 'there' or 'theme':

import { Highlight, Stack, Text } from '@&#8203;mantine/core';

function Demo() {
  return (
    <Stack gap="md">
      <div>
        <Text size="sm" fw={500} mb={5}>
          With whole word matching (wholeWord={'{'}true{'}'})
        </Text>
        <Highlight highlight="the" wholeWord>
          The theme is there
        </Highlight>
      </div>

      <div>
        <Text size="sm" fw={500} mb={5}>
          Without whole word matching (default)
        </Text>
        <Highlight highlight="the">The theme is there</Highlight>
      </div>
    </Stack>
  );
}

Pagination and use-pagination startValue

Pagination component and use-pagination hook now support startValue prop
to define the starting page number. For example, with startValue={5} and total={15},
the pagination range will be from 5 to 15:

import { Text, Pagination } from '@&#8203;mantine/core';

function Demo() {
  return (
    <>
      <Text mb="xs">Pages 5–15 (startValue=5, total=15)</Text>
      <Pagination total={15} startValue={5} defaultValue={5} />
    </>
  );
}

Grid improvements

Grid component no longer uses negative margins for spacing between columns.
Instead, it now uses native CSS gap property, which means you no longer need to use
overflow="hidden" to prevent content overflow caused by negative margins.

Slider vertical orientation

Slider and RangeSlider components now support vertical orientation:

import { RangeSlider, Slider } from '@&#8203;mantine/core';

const marks = [
  { value: 20, label: '20%' },
  { value: 50, label: '50%' },
  { value: 80, label: '80%' },
];

function Demo() {
  return (
    <div style={{ display: 'flex', gap: 40 }}>
      <Slider orientation="vertical" defaultValue={45} marks={marks} />
      <RangeSlider orientation="vertical" defaultValue={[25, 65]} marks={marks} />
    </div>
  );
}

SimpleGrid improvements

SimpleGrid component now supports minColWidth prop to use CSS Grid auto-fill/auto-fit
to automatically adjust the number of columns based on available space and minimum column width.
When minColWidth is set, the cols prop is ignored. Use autoFlow prop to switch between
auto-fill (default) and auto-fit behavior.

import { SimpleGrid } from '@&#8203;mantine/core';

function Demo() {
  return (
    <SimpleGrid minColWidth="200px">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </SimpleGrid>
  );
}

SimpleGrid also now supports autoRows prop to control the size of
implicitly created grid rows:

import { SimpleGrid } from '@&#8203;mantine/core';

function Demo() {
  return (
    <SimpleGrid cols={3} autoRows="minmax(100px, auto)">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </SimpleGrid>
  );
}

Calendar fullWidth prop

Calendar, DatePicker, MonthPicker and YearPicker
components now support fullWidth prop to make the calendar stretch to fill 100% of its parent container width:

import { Calendar } from '@&#8203;mantine/dates';

function Demo() {
  return <Calendar fullWidth />;
}

Namespace types exports

Many Mantine components and hooks now provide namespace exports for related types.
For example, use-disclosure hook types can now be accessed like this:

import { useDisclosure } from '@&#8203;mantine/hooks';

const options: useDisclosure.Options = {
  onOpen: () => console.log('open'),
  onClose: () => console.log('close'),
};

function Demo() {
  const [opened, handlers] = useDisclosure(options);
}

Example of using namespace types with Button props type:

import { Button } from '@&#8203;mantine/core';

const buttonProps: Button.Props = {
    variant: 'filled',
    size: 'md',
    disabled: false,
  };

function Demo() {
  return <Button {...buttonProps}>Click me</Button>;
}

Font weights

New fontWeights property was added to the theme object.
It allows you to control font-weight values used across all components.
The default values are:

  • regular400
  • medium600
  • bold700

Each value is mapped to a CSS variable: --mantine-font-weight-regular, --mantine-font-weight-medium, --mantine-font-weight-bold.
All components that previously used hardcoded font-weight values now use these CSS variables.

For example, to revert the medium font weight from 600 back to 500 (the default in Mantine 8):

import { createTheme, MantineProvider } from '@&#8203;mantine/core';

const theme = createTheme({
  fontWeights: {
    medium: '500',
  },
});

function Demo() {
  return (
    <MantineProvider theme={theme}>
      {/* Your app here */}
    </MantineProvider>
  );
}

@​mantine/mcp-server package

Mantine now includes @mantine/mcp-server package that exposes Mantine
documentation over Model Context Protocol.
It allows AI tools to query Mantine docs and props data through MCP tools instead of raw web scraping.

The server uses static data generated from Mantine documentation and serves:

  • item discovery with list_items
  • full documentation page retrieval with get_item_doc
  • normalized props metadata with get_item_props
  • keyword-based lookup with search_docs

This setup is useful in agent workflows where tools can call MCP functions directly to
retrieve structured data and reduce prompt size.

Basic server configuration:

{
  "mcpServers": {
    "mantine": {
      "command": "npx",
      "args": ["-y", "@&#8203;mantine/mcp-server"],
      "env": {
        "MANTINE_MCP_DATA_URL": "https://mantine.dev/mcp"
      }
    }
  }
}

For setup details, supported tools, and client-specific instructions, see
Mantine with LLMs.

Mantine skills for Claude Code and Codex

Mantine skills for AI coding agents are documented in the
Mantine with LLMs guide.

The guide includes:

  • available skills in mantinedev/skills
  • installation commands for each skill
  • separate usage instructions for Claude Code and Codex

New use-form validators

New isUrl and isOneOf validators were added to @mantine/form package:

  • isUrl – validates that the value is a valid URL. Supports custom protocols and localhost option.
  • isOneOf – validates that the value is included in the given list of allowed values.
import { isOneOf, isUrl, useForm } from '@&#8203;mantine/form';

const form = useForm({
  mode: 'uncontrolled',
  initialValues: { website: '', role: '' },
  validate: {
    website: isUrl('Invalid URL'),
    role: isOneOf(['admin', 'user'], 'Invalid role'),
  },
});

Standard Schema support in use-form

@mantine/form now has built-in support for Standard Schema,
a community specification implemented by Zod v4, Valibot, ArkType, and other schema libraries.
Use schemaResolver to validate forms with any compliant library without installing
a separate resolver package:

import { z } from 'zod/v4';
import { useForm, schemaResolver } from '@&#8203;mantine/form';

const schema = z.object({
  name: z.string().min(2, { error: 'Name should have at least 2 letters' }),
  email: z.email({ error: 'Invalid email' }),
  age: z.number().min(18, { error: 'You must be at least 18 to create an account' }),
});

const form = useForm({
  mode: 'uncontrolled',
  initialValues: { name: '', email: '', age: 16 },
  validate: schemaResolver(schema, { sync: true }),
});

Pass { sync: true } when your schema is synchronous to get synchronous return types
for form.validate(), form.validateField(), and form.isValid().

AppShell static mode

AppShell component now supports mode="static" which renders
all AppShell elements as part of the normal document flow using CSS Grid instead of
fixed positioning. Static mode supports layout="alt" to place navbar and aside
at full height with header and footer adjusted between them.
See AppShell examples for more details.

ScrollArea startScrollPosition

ScrollArea component now supports startScrollPosition prop to set the initial scroll
position when the component mounts:

import { ScrollArea } from '@&#8203;mantine/core';

function Demo() {
  return (
    <ScrollArea h={200} startScrollPosition={{ y: 250 }}>
      {/* ... content */}
    </ScrollArea>
  );
}

useEffectEvent migration in hooks

Five hooks — usePageLeave, useWindowEvent, useHotkeys, useClickOutside, and useCollapse
have been updated to use React 19's stable useEffectEvent. Previously these hooks captured stale
closures or caused unnecessary event listener re-registrations when non-memoized callbacks were
passed. With useEffectEvent, each hook registers a single stable listener that always calls the
latest version of the provided callback, so wrapping callbacks in useCallback or useMemo is no
longer required.

React 19 Activity for keepMounted

Transition, Collapse, Tabs.Panel,
Stepper, and Tree now use React 19's
Activity component when keepMounted is set.
Activity preserves the state of hidden subtrees — form inputs, scroll positions, and any other
component state survive while the content is not visible. Stepper and Tree gain a new
keepMounted prop; all other components already had it.

import { useState } from 'react';
import { Stepper, TextInput } from '@&#8203;mantine/core';

function Demo() {
  const [active, setActive] = useState(0);

  // TextInput values are preserved when navigating between steps
  return (
    <Stepper active={active} onStepClick={setActive} keepMounted>
      <Stepper.Step label="Step 1">
        <TextInput label="Value survives navigation" />
      </Stepper.Step>
      <Stepper.Step label="Step 2">
        <TextInput label="Value survives navigation" />
      </Stepper.Step>
    </Stepper>
  );
}

Documentation updates

  • New Custom components guide explaining how to create custom components with Mantine's styling system
  • New Controlled vs Uncontrolled guide explaining differences between controlled and uncontrolled components
  • HueSlider and AlphaSlider components now have their own documentation pages
  • Uncontrolled documentation and usage with FormData section was added to all inputs components
  • JsonInput documentation now includes custom serialization example with superjson library
  • Pagination documentation now includes URL synchronization examples for Next.js, react-router-dom and nuqs
  • use-form documentation now includes separate examples with all Mantine inputs

Other changes

  • Notifications component now pauses auto close timer of all visible notifications when any notification is hovered (new default). Use pauseResetOnHover="notification" to keep the previous behavior of pausing only the hovered notification.
  • useHeadroom hook now returns { pinned: boolean; scrollProgress: number } object instead of a plain boolean. scrollProgress is a value between 0 (fully hidden) and 1 (fully visible) that can be used for scroll-linked reveal animations. A new scrollDistance option controls how many pixels of scrolling are required to fully reveal or hide the element (default: 100).
  • New useScrollDirection hook detects whether the user is currently scrolling up or down. It returns 'up', 'down', or 'unknown', handles resize events to avoid false direction changes, and always uses the latest state without stale closure issues.
  • Default theme.defaultRadius was changed from sm (4px) to md (8px)
  • light variant in all components now uses different colors values without transparency to improve contrast
  • mod prop now converts camelCase keys to kebab-case for data attributes in all components
  • @mantine/form package now includes built-in Standard Schema support via schemaResolver
  • @mantine/form getInputProps now supports type: 'radio' for individual radio inputs – returns checked/defaultChecked and passes through the radio option value
  • @mantine/form now supports async validation rules. form.validate(), form.validateField() and form.isValid() return results directly when all rules are synchronous and return promises only when async rules are present. New form.validating, form.isValidating(path), validateDebounce and resolveValidationError options were added.
  • createPolymorphicComponent function was renamed to shorter polymorphic for convenience
  • Mantine components now use theme-controlled fontWeights values. The default medium font weight was changed from 500 to 600 for better readability.
  • All Mantine components now support logical margin and padding style props:
    • mis - margin-inline-start
    • mie - margin-inline-end
    • pis - padding-inline-start
    • pie - padding-inline-end
  • Tree component now supports controlled state via expandedState, selectedState and checkedState props.
  • Tree component no longer defines data-hovered attribute for hover state, you need to apply hover styles with &:hover instead. This change improves rendering performance by resolving this issue.
  • Collapse component now uses expanded prop instead of in
  • Collapse, NavLink and Accordion.Panel now support keepMounted={false} prop to unmount collapsed content
  • Select and MultiSelect components now support primitive value types (numbers, booleans, strings) for data and value
  • MultiSelect now supports onMaxValues prop, which is called when the user attempts to select more values than maxValues
  • TagsInput component now supports onMaxTags prop, which is called when the user attempts to add more tags than maxTags
  • Accordion component now supports ref prop
  • Text and Anchor components no longer accept color prop, use c style prop instead
  • PasswordInput component visibility toggle icon was updated
  • Popover and Tooltip components no longer accept positionDependencies prop, it is no longer required
  • TypographyStylesProvider component was renamed to Typography
  • Checkbox component now supports readOnly and withErrorStyles props
  • Spoiler component:
    • initialState prop was renamed to defaultExpanded for consistency with other components
    • New showAriaLabel and hideAriaLabel props allow customizing ARIA labels
  • Checkbox.Group and Switch.Group can now be used in uncontrolled forms and can be accessed through FormData
  • ColorPicker component now supports name and hiddenInputProps props to include color value in uncontrolled form submissions
  • Dialog now enables withBorder by default
  • Pagination component now supports input- prefix for size prop to match input and button sizes
  • FloatingIndicator component now supports onTransitionStart and onTransitionEnd callbacks
  • LoadingOverlay component now supports onEnter, `onEnt

Configuration

📅 Schedule: 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.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Sep 18, 2023

⚠️ No Changeset found

Latest commit: 49a8272

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@socket-security
Copy link
Copy Markdown

socket-security bot commented Sep 18, 2023

Updated dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
@mantine/hooks 6.0.21...7.1.3 None +0/-0 536 kB rtivital
@mantine/core 6.0.21...7.1.3 None +8/-23 9.43 MB rtivital

@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from 5175bd7 to c202c09 Compare September 28, 2023 09:44
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 8379140 to 92c729c Compare October 2, 2023 20:22
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from f7bbe2c to e114e58 Compare October 19, 2023 10:19
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from b410886 to 3163dda Compare October 26, 2023 14:43
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 4 times, most recently from de0ff16 to ed16dfe Compare November 13, 2023 12:13
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch from ed16dfe to c28961c Compare November 18, 2023 12:23
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from b1681cd to 5fd3ae3 Compare November 29, 2023 15:16
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 4 times, most recently from 9b4964d to 24643f9 Compare December 11, 2023 03:26
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 15fe8ed to 6d8cbd6 Compare December 18, 2023 03:36
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 75e7bd3 to cc183fa Compare January 3, 2024 10:56
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 89c6a25 to 54729f6 Compare January 9, 2024 09:14
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from b026a66 to 51c4da4 Compare March 18, 2024 03:22
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 4 times, most recently from 7cb58ba to a3fa2a2 Compare April 1, 2024 04:14
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from e8a125a to 5307a5b Compare April 12, 2024 12:57
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 994f4aa to 66541ff Compare April 22, 2024 03:09
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from aa78110 to 1c878e4 Compare April 29, 2024 04:21
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from 206d0e2 to e211da0 Compare May 8, 2024 10:32
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from a1391f5 to aafe63b Compare May 17, 2024 17:57
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from da11e0b to b3249ec Compare May 27, 2024 03:14
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch from b3249ec to 4c672ef Compare May 30, 2024 10:12
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from 0e0e508 to c13e47c Compare June 13, 2024 10:22
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 2 times, most recently from d867a67 to 9b54f7a Compare July 2, 2024 14:11
@renovate renovate bot force-pushed the renovate/major-mantine-monorepo branch 3 times, most recently from 8b053e0 to 31de66d Compare July 13, 2024 20:33
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.

0 participants