Releases: mantinedev/mantine
7.12.2
What's Changed
[@mantine/hooks]
use-idle: Fix idle countdown not starting if the user did non interact with the page (#6683)[@mantine/core]
ScrollArea: FixonBottomReached
prop not being available inScrollArea.Autosize
component[@mantine/core]
Removechildren
from Checkbox, Radio and Switch types to avoid accidental errors[@mantine/core]
TypographyStylesProvider: Fix incorrect table styles in dark color scheme[@mantine/form]
Fix error thrown for nullable values dirty status check (#6672)[@mantine/core]
Badge: Fix unexpected change to block layout, fix incorrect alignment when fixed width is set (#6698, #6680)[@mantine/core]
ScrollArea: Fix pointer-events being left asnone
after interaction with scrollbar (#6681)[@mantine/core]
Tabs: FixkeepMounted
prop being added as attribute toTabs.Panel
DOM element (#6711)[@mantine/core]
Tree: AddinitialCheckedState
support (#6697)[@mantine/spotlight]
FixSpotlightRoot
component not being exported (#6710)[@mantine/dropzone]
Add7z
andrar
mime types exports (#6702)[@mantine/dates]
DatePickerInput: Fix incorrect hovered date logic when the component receives value update with partial selected date range (#6718)[@mantine/dates]
FixvalueFormatter
prop being added to DateTimePicker types[@mantine/core]
Badge: Fix right/left sections height affecting the alignment of the label[@mantine/core]
Menu: Fix accessibility warning in devtools when the Menu is opened (#6644)
New Contributors
- @timesince made their first contribution in #6654
- @tokyojack made their first contribution in #6718
- @Streusel made their first contribution in #6702
- @fredgig made their first contribution in #6697
- @chimericdream made their first contribution in #6683
- @Aybrea made their first contribution in #6724
Full Changelog: 7.12.1...7.12.2
7.12.1
What's Changed
[@mantine/dates]
DateInput: Fix default date being set to the current date whenminDate
is set to the future (#6646)[@mantine/core]
ScrollArea: Fix incorrect thumb::before styles[@mantine/core]
Fix incorrect active styles of buttons used inside disabled fieldset[@mantine/form]
Fixform.watch
callbacks not being fired whenform.initialize
is called (#6639)[@mantine/core]
Switch: Fix Switch shrinking when large label or description is used (#6531)[@mantine/core]
Combobox: FixCombobox.Search
overflow whenScrollArea
is used in the dropdown (#6562)[@mantine/core]
Accordion: Add missingwithProps
function (#6564)[@mantine/core]
Pill: Fix remove icon overflowing pill container if its background color was changed with Styles API (#6565)[@mantine/core]
PinInput: Allow passing props to individual input elements depending on index withgetInputProps
(#6588)[@mantine/charts]
: Fix LineChart Legend and Tooltip to support nested names (#6536)[@mantine/core]
Tooltip: Add missingTooltip.Group.extend
function (#6576)[@mantine/spotlight]
Fixlimit
prop not working correctly with actions groups (#6632)[@mantine/core]
Badge: Fix text overflow not being handled correctly (#6629)[@mantine/core]
SegmentedControl: Adddata-disabled
attribute to the root element to simplify styling with Styles API (#6625)[@mantine/core]
SegmentedControl: Fix initial position of indicator being broken when the component is used inside other element that has transitions on mount (#6622)[@mantine/core]
TagsInput: FixonKeyDown
prop not working (#6569)[@mantine/charts]
PieChart: FixvalueFormatter
not working on outside labels (#6616)[@mantine/core]
Popover: Fixapply
function ofsize
middleware not being handled correctly (#6598)[@mantine/core]
Chip: Fix incorrect checked padding forsize="xl"
(#6586)[@mantine/dates]
TimeInput: Fix incorrect focus styles of am/pm input (#6579)[@mantine/hook]
use-os: Fix incorrect iPadOS detection (#6535)[@mantine/core]
DatePickerInput: Fix incorrectaria-label
being set on the input element (#6530)[@mantine/core]
Menu: Fix incorrect Escape key handling inside Modal (#6580)
New Contributors
- @vorant94 made their first contribution in #6530
- @hajimism made their first contribution in #6539
- @ziimakc made their first contribution in #6561
- @th3fallen made their first contribution in #6579
- @david-szabo97 made their first contribution in #6586
- @bastiankistner made their first contribution in #6607
- @inx-fldu made their first contribution in #6569
- @michaelperros made their first contribution in #6622
- @risen228 made their first contribution in #6625
- @ddoemonn made their first contribution in #6629
- @yorkeJohn made their first contribution in #6632
- @raulfpl made their first contribution in #6639
- @uriFrischman made their first contribution in #6645
Full Changelog: 7.12.0...7.12.1
7.12.0 🌟
View changelog with demos on mantine.dev website
Notifications at any position
It is now possible to display notifications at any position on the screen
with @mantine/notifications package:
import { Button } from '@mantine/core';
import { notifications } from '@mantine/notifications';
const positions = [
'top-left',
'top-right',
'bottom-left',
'bottom-right',
'top-center',
'bottom-center',
] as const;
function Demo() {
const buttons = positions.map((position) => (
<Button
key={position}
onClick={() =>
notifications.show({
title: `Notification at ${position}`,
message: `Notification at ${position} message`,
position,
})
}
>
{position}
</Button>
));
return <Group>{buttons}</Group>;
}
Subscribe to notifications state
You can now subscribe to notifications state changes with useNotifications
hook:
function Demo() {
const [counter, { increment }] = useCounter();
const notificationsStore = useNotifications();
const showNotification = () => {
notifications.show({
title: `Notification ${counter}`,
message: 'Most notifications are added to queue',
});
increment();
};
return (
<>
<Button onClick={showNotification} mb="md">
Show notification
</Button>
<Text>Notifications state</Text>
<Code block>{JSON.stringify(notificationsStore.notifications, null, 2)}</Code>
<Text mt="md">Notifications queue</Text>
<Code block>{JSON.stringify(notificationsStore.queue, null, 2)}</Code>
</>
);
}
SemiCircleProgress component
New SemiCircleProgress component:
import { SemiCircleProgress } from '@mantine/core';
function Demo() {
return (
<SemiCircleProgress
fillDirection="left-to-right"
orientation="up"
filledSegmentColor="blue"
size={200}
thickness={12}
value={40}
label="Label"
/>
);
}
Tree checked state
Tree component now supports checked state:
import { IconChevronDown } from '@tabler/icons-react';
import { Checkbox, Group, RenderTreeNodePayload, Tree } from '@mantine/core';
import { data } from './data';
const renderTreeNode = ({
node,
expanded,
hasChildren,
elementProps,
tree,
}: RenderTreeNodePayload) => {
const checked = tree.isNodeChecked(node.value);
const indeterminate = tree.isNodeIndeterminate(node.value);
return (
<Group gap="xs" {...elementProps}>
<Checkbox.Indicator
checked={checked}
indeterminate={indeterminate}
onClick={() => (!checked ? tree.checkNode(node.value) : tree.uncheckNode(node.value))}
/>
<Group gap={5} onClick={() => tree.toggleExpanded(node.value)}>
<span>{node.label}</span>
{hasChildren && (
<IconChevronDown
size={14}
style={{ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)' }}
/>
)}
</Group>
</Group>
);
};
function Demo() {
return <Tree data={data} levelOffset={23} expandOnClick={false} renderNode={renderTreeNode} />;
}
Disable specific features in postcss-preset-mantine
You can now disable specific features of the postcss-preset-mantine
by setting them to false
in the configuration object. This feature is available starting from
[email protected]
.
module.exports = {
'postcss-preset-mantine': {
features: {
// Turn off `light-dark` function
lightDarkFunction: false,
// Turn off `postcss-nested` plugin
nested: false,
// Turn off `lighten`, `darken` and `alpha` functions
colorMixAlpha: false,
// Turn off `rem` and `em` functions
remEmFunctions: false,
// Turn off `postcss-mixins` plugin
mixins: false,
},
},
};
Help Center updates
- Server components guide has been updated to include
Component.extend
usage in server components. - A guide on applying input focus styles has been updated to work correctly with PasswordInput and other components in which the
input
selector is not used for actual input element. - The guide on how to disable all inputs in the form now includes additional instructions for use-form.
- New Can I have color schemes other than light and dark? guide explains the difference between color scheme and theme and why Mantine does not support custom color schemes.
- New Why VSCode cannot autoimport Text component? guide explains why VSCode cannot automatically import
Text
component. - New Are Mantine components accessible? question
- New How can I focus the first input with error with use-form? question
- New How to scroll to the top of the form if the form is submitted with errors? question
- New Why my notifications are displayed at a wrong position? question
- New Why my screen is completely empty after I've added notifications package? question
- New Why can I not use value/label data structure with Autocomplete/TagsInput? question
- New Why FileButton does not work in Menu? question
- New How can I display different elements in light and dark color schemes? question
Other changes
- use-interval hook now supports
autoInvoke
option to start the interval automatically when the component mounts. - use-form with
mode="uncontrolled"
now triggers additional rerender when dirty state changes to allow subscribing to form state changes. - ScrollArea component now supports
onTopReached
andonBottomReached
props. The functions are called when the user scrolls to the top or bottom of the scroll area. - Accordion.Panel component now supports
onTransitionEnd
prop that is called when the panel animation completes.
7.11.2
What's Changed
[@mantine/core]
Combobox: Fix inconsistent horizontal dropdown padding[@mantine/core]
Drawer: Fix content overflowing horizontally on mobile whenoffset
is set[@mantine/core]
Drawer: Fix double scrollbar appearing whenoffset
andscrollAreaComponent
props are set[@mantine/carousel]
Fix responsiveslideSize
values working differently from other style props[@mantine/hooks]
use-interval: AddautoInvoke
option support[@mantine/hooks]
use-interval: Fix updates to the function and interval timeout being ignored[@mantine/core]
Anchor: FixlineClamp
prop not working[@mantine/core]
Anchor: Fix text-decoration styles being inconsistent withvariant="gradient"
[@mantine/dates]
DateInput: Fix value flickering with custom timezone (#6517)[@mantine/core]
Burger: FixlineSize
being passed to the DOM node (#6520)[@mantine/charts]
Add support for nested properties indataKey
(#5886)[@mantine/core]
Fix Modal/Drawer headers overlaying custom scrollbar (#6175)[@mantine/charts]
Sparkline: Fix incorrectdata
prop type (#6352)[@mantine/charts]
FixstrokeColor
prop being passed to the DOM element (#6507)[@mantine/core]
FocusTrap: Improve compatibility with React 19 (#6492)[@mantine/hooks]
use-os: Fix iOS being reported as MacOS in several cases (#6511)[@mantine/emotion]
Fix incorrect types ofcreateStyles
classes (#6490)[@mantine/core]
Tooltip: FixfloatingStrategy="fixed"
not working (#6502)
New Contributors
- @lwkchan made their first contribution in #6502
- @Sergio16T made their first contribution in #6517
Full Changelog: 7.11.1...7.11.2
6.0.22
6.x patch
This is a patch for the previous major version, it does not impact 7.x releases.
Changes
[@mantine/core]
Popover: Add size popover middleware to fix overflow issues inPopover.Dropdown
(#5214)[@mantine/core]
Menu: Fix broken focus logic whenkeepMounted
is set (#5565)[@mantine/core]
Switch: fix accessibility issues (#5755)[@mantine/core]
Fix Typescript 5.5 compatibility
Full Changelog: 6.0.21...6.0.22
7.11.1
What's Changed
[@mantine/core]
Add option to displaynothingFoundMessage
when data is empty in Select and MultiSelect components (#6477)[@mantine/core]
Tooltip: AdddefaultOpened
prop support (#6466)[@mantine/core]
PinInput: Fix incorrect rtl logic (#6382)[@mantine/core]
Popover: FixfloatingStrategy="fixed"
not havingposition:fixed
styles (#6419)[@mantine/spotlight]
Fix spotlight not working correctly with shadow DOM (#6400)[@mantine/form]
FixonValuesChange
using stale values (#6392)[@mantine/carousel]
FixonSlideChange
using stale props values (#6393)[@mantine/charts]
Fix unexpected padding on the right side of the chart in BarChart, AreaChart and LineChart components (#6467)[@mantine/core]
Select: FixonChange
being called with the already selected if it has been picked from the dropdown (#6468)[@mantine/dates]
DatePickerInput: FixhighlightToday
not working (#6471)[@mantine/core]
NumberInput: Fix incorrect handling of numbers larger than max safe integer on blur (#6407)[@mantine/core]
Tooltip: Fix tooltip arrow being incompatible with headless mode (#6458)[@mantine/core]
ActionIcon: Fix loading styles inconsistency with Button component (#6460)[@mantine/charts]
PieChart: Fix key error for duplicatedname
data (#6067)[@mantine/core]
Modal: FixremoveScrollProps.ref
not being compatible with React 19 (#6446)[@mantine/core]
TagsInput: FixselectFirstOptionOnChange
prop not working (#6337)[@mantine/hooks]
use-eye-dropper: Fix Opera being incorrectly detected as a supported browser (#6307)[@mantine/core]
Fix:host
selector now working correctly incssVariablesSelector
of MantineProvider (#6404)[@mantine/core]
TagsInput: FixonChange
being called twice when Enter key is pressed in some cases (#6416)[@mantine/modals]
Fix Modal overrides type augmentation not working with TypeScript 5.5 (#6443)[@mantine/core]
Tree: FixlevelOffset
prop being added to the root DOM element (#6461)
New Contributors
- @bsl-zcs made their first contribution in #6461
- @florisdg made their first contribution in #6443
- @snlacks made their first contribution in #6425
- @lid0a made their first contribution in #6415
- @Knamer95 made their first contribution in #6416
- @yyytae0 made their first contribution in #6404
- @toanxyz made their first contribution in #6388
- @viktorkasap made their first contribution in #6307
- @alexlapp made their first contribution in #6337
- @brycefranzen made their first contribution in #6446
- @marcobiedermann made their first contribution in #6442
- @mullwar made their first contribution in #6067
- @gruschis made their first contribution in #6400
- @jpranays made their first contribution in #6466
Full Changelog: 7.11.0...7.11.1
7.11.0 👁️
View changelog with demos on mantine.dev website
withProps function
All Mantine components now have withProps
static function that can be used to
add default props to the component:
import { IMaskInput } from 'react-imask';
import { Button, InputBase } from '@mantine/core';
const LinkButton = Button.withProps({
component: 'a',
target: '_blank',
rel: 'noreferrer',
variant: 'subtle',
});
const PhoneInput = InputBase.withProps({
mask: '+7 (000) 000-0000',
component: IMaskInput,
label: 'Your phone number',
placeholder: 'Your phone number',
});
function Demo() {
return (
<>
{/* You can pass additional props to components created with `withProps` */}
<LinkButton href="https://mantine.dev">Mantine website</LinkButton>
{/* Component props override default props defined in `withProps` */}
<PhoneInput placeholder="Personal phone" />
</>
);
}
Avatar initials
Avatar component now supports displaying initials with auto generated color based on the given name
value.
To display initials instead of the default placeholder, set name
prop
to the name of the person, for example, name="John Doe"
. If the name
is set, you can use color="initials"
to generate color based on the name:
import { Avatar, Group } from '@mantine/core';
const names = [
'John Doe',
'Jane Mol',
'Alex Lump',
'Sarah Condor',
'Mike Johnson',
'Kate Kok',
'Tom Smith',
];
function Demo() {
const avatars = names.map((name) => <Avatar key={name} name={name} color="initials" />);
return <Group>{avatars}</Group>;
}
BubbleChart component
New BubbleChart component:
import { BubbleChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<BubbleChart
h={60}
data={data}
range={[16, 225]}
label="Sales/hour"
color="lime.6"
dataKey={{ x: 'hour', y: 'index', z: 'value' }}
/>
);
}
BarChart waterfall type
BarChart component now supports waterfall
type
which is useful for visualizing changes in values over time:
import { BarChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<BarChart
h={300}
data={data}
dataKey="item"
type="waterfall"
series={[{ name: 'Effective tax rate in %', color: 'blue' }]}
withLegend
/>
);
}
LineChart gradient type
LineChart component now supports gradient
type
which renders line chart with gradient fill:
import { LineChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<LineChart
h={300}
data={data}
series={[{ name: 'temperature', label: 'Avg. Temperature' }]}
dataKey="date"
type="gradient"
gradientStops={[
{ offset: 0, color: 'red.6' },
{ offset: 20, color: 'orange.6' },
{ offset: 40, color: 'yellow.5' },
{ offset: 70, color: 'lime.5' },
{ offset: 80, color: 'cyan.5' },
{ offset: 100, color: 'blue.5' },
]}
strokeWidth={5}
curveType="natural"
yAxisProps={{ domain: [-25, 40] }}
valueFormatter={(value) => `${value}°C`}
/>
);
}
Right Y axis
LineChart, BarChart and AreaChart components
now support rightYAxis
prop which renders additional Y axis on the right side of the chart:
import { LineChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<LineChart
h={300}
data={data}
dataKey="name"
withRightYAxis
yAxisLabel="uv"
rightYAxisLabel="pv"
series={[
{ name: 'uv', color: 'pink.6' },
{ name: 'pv', color: 'cyan.6', yAxisId: 'right' },
]}
/>
);
}
RadarChart legend
RadarChart component now supports legend:
import { RadarChart } from '@mantine/charts';
import { data } from './data';
function Demo() {
return (
<RadarChart
h={300}
data={data}
dataKey="product"
withPolarRadiusAxis
withLegend
series={[
{ name: 'Sales January', color: 'blue.6', opacity: 0.2 },
{ name: 'Sales February', color: 'orange.6', opacity: 0.2 },
]}
/>
);
}
TagsInput acceptValueOnBlur
TagsInput component behavior has been changed. Now By default,
if the user types in a value and blurs the input, the value is added to the list.
You can change this behavior by setting acceptValueOnBlur
to false
. In this case, the value is added
only when the user presses Enter
or clicks on a suggestion.
import { TagsInput } from '@mantine/core';
function Demo() {
return (
<>
<TagsInput
label="Value IS accepted on blur"
placeholder="Enter text, then blur the field"
data={['React', 'Angular', 'Svelte']}
acceptValueOnBlur
/>
<TagsInput
label="Value IS NOT accepted on blur"
placeholder="Enter text, then blur the field"
data={['React', 'Angular', 'Svelte']}
acceptValueOnBlur={false}
mt="md"
/>
</>
);
}
Transition delay
Transition component now supports enterDelay
and exitDelay
props to delay transition start:
import { useState } from 'react';
import { Button, Flex, Paper, Transition } from '@mantine/core';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<Flex maw={200} pos="relative" justify="center" m="auto">
<Button onClick={() => setOpened(true)}>Open dropdown</Button>
<Transition mounted={opened} transition="pop" enterDelay={500} exitDelay={300}>
{(transitionStyle) => (
<Paper
shadow="md"
p="xl"
h={120}
pos="absolute"
inset={0}
bottom="auto"
onClick={() => setOpened(false)}
style={{ ...transitionStyle, zIndex: 1 }}
>
Click to close
</Paper>
)}
</Transition>
</Flex>
);
}
Documentation updates
- New segmented progress example has been added to
Progress
component documentation - Select, TagsInput and MultiSelect components documentation now includes additional demo on how to change the dropdown width
- New DatePicker example for
excludeDate
prop
Other changes
- Pagination component now supports
hideWithOnePage
prop which hides pagination when there is only one page - Spoiler component now supports controlled expanded state with
expanded
andonExpandedChange
props - Burger component now supports
lineSize
prop to change lines height - Calendar, DatePicker and other similar components now support
highlightToday
prop to highlight today's date
7.10.2
What's Changed
[@mantine/core]
Select: Fix incorrect state changes handling when bothvalue
andsearchValue
are controlled (#6272)[@mantine/core]
Stepper: FixautoContrast
prop being added to the DOM element[@mantine/charts]
PieChart: Fix inner label not using formatted value (#6328)[@mantine/core]
Fix incorrect color resolving logic in border style prop resolver (#6326)[@mantine/modals]
Fix incorrect styles of the confirmation modal when it is used without any description (#6325)[@mantine/core]
ScrollArea: Fix click events being triggered when scrollbar drag is released over an interactive element in Firefox (#6354)[@mantine/core]
Combobox: Fix clicks on footer and header triggering dropdown close (#6344)[@mantine/core]
PasswordInput: FixwithErrorStyles
prop being passed to the DOM element (#6348)
New Contributors
- @stefanzmf made their first contribution in #6344
- @Prasiddha22 made their first contribution in #6325
- @ShionTerunaga made their first contribution in #6332
- @djdduty made their first contribution in #6326
- @Jones-Griffin made their first contribution in #6328
- @floriankapaun made their first contribution in #6272
Full Changelog: 7.10.1...7.10.2
7.10.1
What's Changed
[@mantine/charts]
BarChart: Add waterfall type (#6231)[@mantine/form]
Fixform.setFieldError
called insideform.onSubmit
not working correctly in some cases (#6101)[@mantine/core]
SegmentedControl: Fix false error reported by React 18.3+ for incorrect key prop usage[@mantine/hooks]
use-fetch: Fix incorrect error handling (#6278)[@mantine/core]
Fixbd
style prop not being applied in some components (#6282)[@mantine/core]
NumberInput: Fix incorrect leading zeros handling (#6232)[@mantine/core]
NumberInput: Fix incorrect logic while editing decimal values (#6232)[@mantine/core]
ScrollArea: Fix scrollbar flickering on reveal with hover and scroll types (#6218)[@mantine/hooks]
Update use-throttled-* hooks to emit updates on trailing edges (#6257)[@mantine/core]
Input: AddinputSize
prop to setsize
html attribute on the input element
New Contributors
- @a-kon made their first contribution in #6265
- @dfaust made their first contribution in #6257
- @ElTupac made their first contribution in #6278
Full Changelog: 7.10.0...7.10.1
7.10.0 😎
View changelog with demos on mantine.dev website
Tree component
New Tree component:
import { IconFolder, IconFolderOpen } from '@tabler/icons-react';
import { Group, RenderTreeNodePayload, Tree } from '@mantine/core';
import { CssIcon, NpmIcon, TypeScriptCircleIcon } from '@mantinex/dev-icons';
import { data, dataCode } from './data';
import classes from './Demo.module.css';
interface FileIconProps {
name: string;
isFolder: boolean;
expanded: boolean;
}
function FileIcon({ name, isFolder, expanded }: FileIconProps) {
if (name.endsWith('package.json')) {
return <NpmIcon size={14} />;
}
if (name.endsWith('.ts') || name.endsWith('.tsx') || name.endsWith('tsconfig.json')) {
return <TypeScriptCircleIcon size={14} />;
}
if (name.endsWith('.css')) {
return <CssIcon size={14} />;
}
if (isFolder) {
return expanded ? (
<IconFolderOpen color="var(--mantine-color-yellow-9)" size={14} stroke={2.5} />
) : (
<IconFolder color="var(--mantine-color-yellow-9)" size={14} stroke={2.5} />
);
}
return null;
}
function Leaf({ node, expanded, hasChildren, elementProps }: RenderTreeNodePayload) {
return (
<Group gap={5} {...elementProps}>
<FileIcon name={node.value} isFolder={hasChildren} expanded={expanded} />
<span>{node.label}</span>
</Group>
);
}
function Demo() {
return (
<Tree
classNames={classes}
selectOnClick
clearSelectionOnOutsideClick
data={data}
renderNode={(payload) => <Leaf {...payload} />}
/>
);
}
form.getInputNode
New form.getInputNode(path)
handler returns input DOM node for the given field path.
Form example, it can be used to focus input on form submit if there is an error:
import { Button, Group, TextInput } from '@mantine/core';
import { isEmail, isNotEmpty, useForm } from '@mantine/form';
function Demo() {
const form = useForm({
mode: 'uncontrolled',
initialValues: {
name: '',
email: '',
},
validate: {
name: isNotEmpty('Name is required'),
email: isEmail('Invalid email'),
},
});
return (
<form
onSubmit={form.onSubmit(
(values) => console.log(values),
(errors) => {
const firstErrorPath = Object.keys(errors)[0];
form.getInputNode(firstErrorPath)?.focus();
}
)}
>
<TextInput
withAsterisk
label="Your name"
placeholder="Your name"
key={form.key('name')}
{...form.getInputProps('name')}
/>
<TextInput
withAsterisk
label="Your email"
placeholder="[email protected]"
key={form.key('email')}
{...form.getInputProps('email')}
/>
<Group justify="flex-end" mt="md">
<Button type="submit">Submit</Button>
</Group>
</form>
);
}
Container queries in SimpleGrid
You can now use container queries
in SimpleGrid component. With container queries, grid columns and spacing
will be adjusted based on the container width, not the viewport width.
Example of using container queries. To see how the grid changes, resize the root element
of the demo with the resize handle located at the bottom right corner of the demo:
import { SimpleGrid } from '@mantine/core';
function Demo() {
return (
// Wrapper div is added for demonstration purposes only,
// it is not required in real projects
<div style={{ resize: 'horizontal', overflow: 'hidden', maxWidth: '100%' }}>
<SimpleGrid
type="container"
cols={{ base: 1, '300px': 2, '500px': 5 }}
spacing={{ base: 10, '300px': 'xl' }}
>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</SimpleGrid>
</div>
);
}
Checkbox and Radio indicators
New Checkbox.Indicator and Radio.Indicator
components look exactly the same as Checkbox
and Radio
components, but they do not
have any semantic meaning, they are just visual representations of checkbox and radio states.
Checkbox.Indicator
component:
import { Checkbox, Group } from '@mantine/core';
function Demo() {
return (
<Group>
<Checkbox.Indicator />
<Checkbox.Indicator checked />
<Checkbox.Indicator indeterminate />
<Checkbox.Indicator disabled />
<Checkbox.Indicator disabled checked />
<Checkbox.Indicator disabled indeterminate />
</Group>
);
}
Radio.Indicator
component:
import { Group, Radio } from '@mantine/core';
function Demo() {
return (
<Group>
<Radio.Indicator />
<Radio.Indicator checked />
<Radio.Indicator disabled />
<Radio.Indicator disabled checked />
</Group>
);
}
Checkbox and Radio cards
New Checkbox.Card and Radio.Card
components can be used as replacements for Checkbox
and Radio
to build custom cards/buttons/etc.
that work as checkboxes and radios. Components are accessible by default and support the same
keyboard interactions as input[type="checkbox"]
and input[type="radio"]
.
Checkbox.Card
component:
import { useState } from 'react';
import { Checkbox, Group, Text } from '@mantine/core';
import classes from './Demo.module.css';
function Demo() {
const [checked, setChecked] = useState(false);
return (
<Checkbox.Card
className={classes.root}
radius="md"
checked={checked}
onClick={() => setChecked((c) => !c)}
>
<Group wrap="nowrap" align="flex-start">
<Checkbox.Indicator />
<div>
<Text className={classes.label}>@mantine/core</Text>
<Text className={classes.description}>
Core components library: inputs, buttons, overlays, etc.
</Text>
</div>
</Group>
</Checkbox.Card>
);
}
Checkbox.Card
component with Checkbox.Group
:
import { useState } from 'react';
import { Checkbox, Group, Stack, Text } from '@mantine/core';
import classes from './Demo.module.css';
const data = [
{
name: '@mantine/core',
description: 'Core components library: inputs, buttons, overlays, etc.',
},
{ name: '@mantine/hooks', description: 'Collection of reusable hooks for React applications.' },
{ name: '@mantine/notifications', description: 'Notifications system' },
];
function Demo() {
const [value, setValue] = useState<string[]>([]);
const cards = data.map((item) => (
<Checkbox.Card className={classes.root} radius="md" value={item.name} key={item.name}>
<Group wrap="nowrap" align="flex-start">
<Checkbox.Indicator />
<div>
<Text className={classes.label}>{item.name}</Text>
<Text className={classes.description}>{item.description}</Text>
</div>
</Group>
</Checkbox.Card>
));
return (
<>
<Checkbox.Group
value={value}
onChange={setValue}
label="Pick packages to install"
description="Choose all packages that you will need in your application"
>
<Stack pt="md" gap="xs">
{cards}
</Stack>
</Checkbox.Group>
<Text fz="xs" mt="md">
CurrentValue: {value.join(', ') || '–'}
</Text>
</>
);
}
Radio.Card
component:
import { useState } from 'react';
import { Group, Radio, Text } from '@mantine/core';
import classes from './Demo.module.css';
function Demo() {
const [checked, setChecked] = useState(false);
return (
<Radio.Card
className={classes.root}
radius="md"
checked={checked}
onClick={() => setChecked((c) => !c)}
>
<Group wrap="nowrap" align="flex-start">
<Radio.Indicator />
<div>
<Text className={classes.label}>@mantine/core</Text>
<Text className={classes.description}>
Core components library: inputs, buttons, overlays, etc.
</Text>
</div>
</Group>
</Radio.Card>
);
}
Radio.Card
component with Radio.Group
:
import { useState } from 'react';
import { Group, Radio, Stack, Text } from '@mantine/core';
import classes from './Demo.module.css';
const data = [
{
name: '@mantine/core',
description: 'Core components library: inputs, buttons, overlays, etc.',
},
{ name: '@mantine/hooks', description: 'Collection of reusable hooks for React applications.' },
{ name: '@mantine/notifications', description: 'Notifications system' },
];
function Demo() {
const [value, setValue] = useState<string | null>(null);
const cards = data.map((item) => (
<Radio.Card className={classes.root} radius="md" value={item.name} key={item.name}>
<Group wrap="nowrap" align="flex-start">
<Radio.Indicator />
<div>
<Text className={classes.label}>{item.name}</Text>
<Text className={classes.description}>{item.description}</Text>
</div>
</Group>
</Radio.Card>
));
return (
<>
<Radio.Group
value={value}
onChange={setValue}
label="Pick one package to install"
description="Choose a package that you will need in your application"
>
<Stack pt="md" gap="xs">
{cards}
...