Render button or link with button styles from mantine theme




Button has 6 variants: white, gradient, filled, light, outline and link:

Default Button color is theme.primaryColor, to change color and variant pass color and variant props:

<Button color="red" /> // filled button with red color
<Button variant="outline" /> // outline button with theme.primaryColor color
<Button variant="link" color="indigo" /> // indigo link button

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
<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: 'grape', to: 'pink', deg: 35 }}>Grape pink</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:

<Button leftIcon={<DatabaseIcon />} variant="white">
Connect to database

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, either right or left
  • loaderProps – props spread to Loader component, you can choose loader type, size and any other supported prop
<Button leftIcon={<DatabaseIcon size={14} />}>
{loading ? 'Connecting' : 'Connect'} to database


You can change styles of any element in button component with Styles API to match your design requirements:

rel="noopener noreferrer"
leftIcon={<TwitterLogoIcon width={18} height={18} />}
root: {
backgroundColor: '#00acee',
border: 0,
height: 42,
paddingLeft: 20,
paddingRight: 20,
leftIcon: {
marginRight: 15,
Follow on Twitter


Set compact prop to reduce button height and horizontal padding:

<Button compact>My compact button</Button>

Size and radius

Control button font-size, height and padding with size and border-radius with radius props. Both props have predefined values: xs, sm, md, lg, xl. Alternatively, you can use a number to set radius in px:

<Button radius="lg" /> // -> theme predefined large radius
<Button radius={10} /> // -> { borderRadius: '10px' }
<Button size="sm" /> // -> predefined small size
Predefined sizes from xs to xl:
Predefined compact sizes from xs to xl:
Theme radius from xs to xl:

You can get predefined button heights by importing BUTTON_SIZES:

import { BUTTON_SIZES } from '@mantine/core';
SizeButton height

Full width and overflow

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

<div style={{ width: 200 }}>
<Button variant="filled" fullWidth>
Full width button
<div style={{ width: 120 }}>
<Button variant="filled" fullWidth>
Button with overflow

Change root element

You can use Button component both as button and a elements:

leftIcon={<ExternalLinkIcon />}
Mantine docs

Usage with react-router and other libraries

You can use Button component with react-router-dom or other similar libraries by passing Link as component to Button:

import { Link } from 'react-router-dom';
import { Button } from '@mantine/core';
function Demo() {
return (
<Button component={Link} to="/react-router">
React router link

Usage with Next Link

Next Link component requires ref prop usage, however all Mantine components use elementRef, to make Button and other similar components work with Next Link, create wrapper component in your components folder:

// This component can be reused in every Mantine component which supports component pass through
import React, { forwardRef } from 'react';
import Link from 'next/link';
export const NextLink = forwardRef(
{ href, ...others }: React.ComponentPropsWithoutRef<typeof Link>,
ref: React.ForwardedRef<HTMLAnchorElement>
) => (
<Link href={href}>
{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}
<a {...others} ref={ref} />

And then pass it to Button or other component:

<Button component={NextLink} href="/hello">
Next Link button

Get element ref

You can get root element ref with elementRef prop:

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

Unstyled button

To create custom buttons not related to Button component, use UnstyledButton component, it renders regular button without default browser styles and with Mantine focus styles:

import { UnstyledButton } from '@mantine/core';
function Demo() {
return (
<UnstyledButton onClick={() => console.log('try focusing button with tab')}>
<Avatar size={40} color="blue">BH</Avatar>
<Text>Bob Handsome</Text>
<Text size="xs" color="gray">bob@handsome.inc</Text>


You need to pass additional types to use custom component with TypeScript in case you need full type coverage for events and elementRef:

// With element
<Button<'button', HTMLButtonElement>
onClick={(event) => console.log(event)}
elementRef={(node) => {
window.myRef = node;
// With component
<Button<typeof Link, HTMLAnchorElement>
onClick={(event) => console.log(event)}
elementRef={(node) => {
window.myRef = node;
Build fully functional accessible web applications with ease
Your feedback is most valuable contribution to the project, please share how you use Mantine, what features are missing and what is done good
Leave feedback