Buttonpolymorphic

Render button or link with button styles from mantine theme
Import

Usage

Color
Radius
xs
sm
md
lg
xl
Size
xs
sm
md
lg
xl
import { Button } from '@mantine/core';
function Demo() {
return (
<Button>
Settings
</Button>
);
}

Variants

Gradient variant

To use gradient as Button background:

  • set variant to gradient
  • set gradient to { from: 'color-from', to: 'color-to', deg: 135 }, where
    • color-from and color-to are color from theme.colors
    • deg is linear gradient deg
import { Button } from '@mantine/core';
function Demo() {
return (
<>
<Button variant="gradient" gradient={{ from: 'indigo', to: 'cyan' }}>Indigo cyan</Button>
<Button variant="gradient" gradient={{ from: 'teal', to: 'lime', deg: 105 }}>Lime green</Button>
<Button variant="gradient" gradient={{ from: 'teal', to: 'blue', deg: 60 }}>Teal blue</Button>
<Button variant="gradient" gradient={{ from: 'orange', to: 'red' }}>Orange red</Button>
<Button variant="gradient" gradient={{ from: '#ed6ea0', to: '#ec8c69', deg: 35 }}>Peach</Button>
</>
);
}

White variant

White is a variant in which button background color is always white (both in light and dark theme) and color is controlled with color prop:

Color
import { Button } from '@mantine/core';
import { IconDatabase } from '@tabler/icons-react';
function Demo() {
return (
<Button leftIcon={<IconDatabase />} variant="white">
Connect to database
</Button>
);
}

Loading state

Button supports loading state. In this state Loader component replaces left or right icon, button becomes disabled and white or dark overlay is added.

You can control loading state and Loader component with following props:

  • loading – enable loading state
  • loaderPosition – Loader position relative to button label, left, right or center
  • loaderProps – props spread to Loader component, you can choose loader type, size and any other supported prop
LoaderPosition
import { IconDatabase } from '@tabler/icons-react';
import { Button } from '@mantine/core';
function Demo() {
return (
<Button leftIcon={<IconDatabase size="1rem" />}>
Connect to database
</Button>
);
}

Styles API

import { Group, Button, rem } from '@mantine/core';
import { IconBrandTwitter } from '@tabler/icons-react';
function Demo() {
return (
<Group position="center">
<Button
component="a"
target="_blank"
rel="noopener noreferrer"
href="https://twitter.com/mantinedev"
leftIcon={<IconBrandTwitter size={rem(18)} />}
styles={(theme) => ({
root: {
backgroundColor: '#00acee',
border: 0,
height: rem(42),
paddingLeft: rem(20),
paddingRight: rem(20),
'&:not([data-disabled])': theme.fn.hover({
backgroundColor: theme.fn.darken('#00acee', 0.05),
}),
},
leftIcon: {
marginRight: theme.spacing.md,
},
})}
>
Follow on Twitter
</Button>
</Group>
);
}

Compact

import { Button } from '@mantine/core';
function Demo() {
return <Button compact>My compact button</Button>;
}

Full width and overflow

Button can take full width of container if you set fullWidth prop. If button content is too large for its container, overflown content will be hidden:

import { Button, Flex, Box } from '@mantine/core';
function Demo() {
return (
<Flex gap="md">
<Box w={200}>
<Button fullWidth variant="outline">
Full width button
</Button>
</Box>
<Box w={140}>
<Button fullWidth variant="outline">
Button with overflow
</Button>
</Box>
</Flex>
);
}

Button.Group

Orientation
import { Button } from '@mantine/core';
function Demo() {
return (
<Button.Group>
<Button variant="default">First</Button>
<Button variant="default">Second</Button>
<Button variant="default">Third</Button>
</Button.Group>
);
}

Note that you cannot wrap child Button components with any additional elements:

import { Button } from '@mantine/core';
function Demo() {
return (
<Button.Group>
<div>
<Button>This will not work</Button>
</div>
<Button>Buttons will have incorrect borders</Button>
</Button.Group>
);
}

If you want to use Tooltip, Popover or other overlay component, it is required to set withinPortal prop:

import { Button, Tooltip } from '@mantine/core';
function Demo() {
return (
<Button.Group>
<Tooltip label="Working as expected" withinPortal>
<Button>With Tooltip</Button>
</Tooltip>
<Button>Regular button</Button>
</Button.Group>
);
}

data- attributes

Button has the following attributes on the root element:

  • data-disabled when disabled prop is true
  • data-loading when loading prop is true

You can customize disabled and loading styles with these attributes:

import { Button } from '@mantine/core';
function Demo() {
return (
<Button
sx={{
'&[data-disabled]': { opacity: 0.4 },
'&[data-loading]': { backgroundColor: 'red' },
}}
/>
);
}

Disabled button with tooltip

Disabled buttons do not trigger onMouseLeave (react issue). If you need to display tooltip for disabled button, do not use disabled prop, instead set data-disabled attribute:

import { Button, Group, Tooltip } from '@mantine/core';
function Demo() {
return (
<Group position="center">
<Tooltip label="Tooltip for disabled button">
<Button
data-disabled
sx={{ '&[data-disabled]': { pointerEvents: 'all' } }}
onClick={(event) => event.preventDefault()}
>
Disabled button
</Button>
</Tooltip>
</Group>
);
}

Polymorphic component

Button is a polymorphic component, you can change root element:

import { Button } from '@mantine/core';
import { IconExternalLink } from '@tabler/icons-react';
function Demo() {
return (
<Button component="a" href="#" variant="outline" leftIcon={<IconExternalLink size="0.9rem" />}>
Open in new tab
</Button>
);
}

Get ref

import { useRef } from 'react';
import { Button } from '@mantine/core';
function Demo() {
const ref = useRef<HTMLButtonElement>(null);
return <Button ref={ref} />;
}

Button component props

NameTypeDescription
children
ReactNode
Button label
color
MantineColor
Button color from theme
compact
boolean
Reduces vertical and horizontal spacing
disabled
boolean
Disabled state
fullWidth
boolean
Sets button width to 100% of parent element
gradient
MantineGradient
Controls gradient settings in gradient variant only
leftIcon
ReactNode
Adds icon before button label
loaderPosition
"left" | "right" | "center"
Loader position relative to button label
loaderProps
LoaderProps
Props spread to Loader component
loading
boolean
Indicate loading state
radius
number | "xs" | "sm" | "md" | "lg" | "xl"
Key of theme.radius or any valid CSS value to set border-radius, theme.defaultRadius by default
rightIcon
ReactNode
Adds icon after button label
size
"xs" | "sm" | "md" | "lg" | "xl"
Predefined button size
type
"button" | "reset" | "submit"
Button type attribute
uppercase
boolean
Set text-transform to uppercase
variant
Variants<"outline" | "white" | "light" | "default" | "filled" | "gradient" | "subtle">
Controls button appearance

Button.Group component props

NameTypeDescription
buttonBorderWidth
string | number
Child <Button /> border width
children
ReactNode
<Button /> components
orientation
"horizontal" | "vertical"
Switch between vertical and horizontal orientation

Button component Styles API

NameStatic selectorDescription
root.mantine-Button-rootRoot button element
icon.mantine-Button-iconShared icon styles
leftIcon.mantine-Button-leftIconLeft icon
rightIcon.mantine-Button-rightIconRight icon
centerLoader.mantine-Button-centerLoaderCenter loader
inner.mantine-Button-innerContains label, left and right icons
label.mantine-Button-labelContains button children