React components library focused on usability, accessibility and developer experience
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
@mantine/core provides comprehensive button and typography components for creating interactive elements and displaying text content with consistent styling, accessibility features, and theme integration.
Primary button component with extensive styling options and variants.
interface ButtonProps {
/** Button children */
children?: React.ReactNode;
/** Button variant */
variant?: 'filled' | 'light' | 'outline' | 'subtle' | 'transparent' | 'white' | 'default' | 'gradient';
/** Button size */
size?: MantineSize | string;
/** Button color */
color?: MantineColor;
/** Button radius */
radius?: MantineRadius;
/** If true, button will take full width of container */
fullWidth?: boolean;
/** If true, button will be compact */
compact?: boolean;
/** Button left section */
leftSection?: React.ReactNode;
/** Button right section */
rightSection?: React.ReactNode;
/** If true, button will be disabled */
disabled?: boolean;
/** If true, button will show loading state */
loading?: boolean;
/** Loading text override */
loaderProps?: LoaderProps;
/** Button type */
type?: 'button' | 'submit' | 'reset';
/** Button gradient (for gradient variant) */
gradient?: MantineGradient;
/** If true, button will automatically adjust text contrast */
autoContrast?: boolean;
/** Button component type */
component?: React.ElementType;
}
interface ButtonGroupProps {
/** Group children */
children: React.ReactNode;
/** Group orientation */
orientation?: 'horizontal' | 'vertical';
/** If true, buttons will be borderless */
borderWidth?: number;
}Usage Example:
import { Button, Group } from '@mantine/core';
function ButtonDemo() {
return (
<Group>
<Button variant="filled">Filled button</Button>
<Button variant="light">Light button</Button>
<Button variant="outline">Outline button</Button>
<Button variant="subtle">Subtle button</Button>
<Button variant="transparent">Transparent button</Button>
<Button variant="white">White button</Button>
<Button variant="gradient" gradient={{ from: 'indigo', to: 'cyan' }}>
Gradient button
</Button>
</Group>
);
}
// Button with sections
function ButtonWithSections() {
return (
<Group>
<Button leftSection="📧" variant="default">
Send email
</Button>
<Button rightSection="→">
Continue
</Button>
<Button
leftSection="💾"
rightSection="⌘S"
variant="light"
>
Save file
</Button>
</Group>
);
}
// Button states
function ButtonStates() {
return (
<Group>
<Button loading>Loading button</Button>
<Button disabled>Disabled button</Button>
<Button
loading
loaderProps={{ type: 'dots' }}
>
Custom loader
</Button>
</Group>
);
}
// Button group
function ButtonGroupDemo() {
return (
<Button.Group>
<Button variant="default">First</Button>
<Button variant="default">Second</Button>
<Button variant="default">Third</Button>
</Button.Group>
);
}Icon button component for single icon actions.
interface ActionIconProps {
/** Icon children */
children?: React.ReactNode;
/** ActionIcon variant */
variant?: 'filled' | 'light' | 'outline' | 'subtle' | 'transparent' | 'white' | 'default' | 'gradient';
/** ActionIcon size */
size?: MantineSize | string | number;
/** ActionIcon color */
color?: MantineColor;
/** ActionIcon radius */
radius?: MantineRadius;
/** If true, ActionIcon will be disabled */
disabled?: boolean;
/** If true, ActionIcon will show loading state */
loading?: boolean;
/** Loading props */
loaderProps?: LoaderProps;
/** ActionIcon gradient (for gradient variant) */
gradient?: MantineGradient;
/** If true, ActionIcon will automatically adjust text contrast */
autoContrast?: boolean;
}
interface ActionIconGroupProps {
/** Group children */
children: React.ReactNode;
/** Group orientation */
orientation?: 'horizontal' | 'vertical';
/** Group border width */
borderWidth?: number;
}Usage Example:
import { ActionIcon, Group } from '@mantine/core';
function ActionIconDemo() {
return (
<Group>
<ActionIcon variant="filled" aria-label="Settings">
⚙️
</ActionIcon>
<ActionIcon variant="light" aria-label="Search">
🔍
</ActionIcon>
<ActionIcon variant="outline" color="red" aria-label="Delete">
🗑️
</ActionIcon>
<ActionIcon loading aria-label="Loading">
📧
</ActionIcon>
<ActionIcon size="xl" variant="gradient" gradient={{ from: 'blue', to: 'cyan' }}>
🎨
</ActionIcon>
</Group>
);
}
// ActionIcon group
function ActionIconGroupDemo() {
return (
<ActionIcon.Group>
<ActionIcon variant="default" aria-label="Bold">
B
</ActionIcon>
<ActionIcon variant="default" aria-label="Italic">
I
</ActionIcon>
<ActionIcon variant="default" aria-label="Underline">
U
</ActionIcon>
</ActionIcon.Group>
);
}Base button component without default styles.
interface UnstyledButtonProps {
/** Button children */
children?: React.ReactNode;
/** Button component type */
component?: React.ElementType;
/** If true, button will be disabled */
disabled?: boolean;
/** Called when button is clicked */
onClick?: (event: React.MouseEvent) => void;
}Usage Example:
import { UnstyledButton, Text, Group, rem } from '@mantine/core';
function UnstyledButtonDemo() {
return (
<UnstyledButton
onClick={() => console.log('clicked')}
style={{
display: 'block',
width: '100%',
padding: rem(14),
borderRadius: rem(4),
color: 'var(--mantine-color-text)',
textDecoration: 'none',
'&:hover': {
backgroundColor: 'var(--mantine-color-gray-0)',
},
}}
>
<Group>
<div>
<Text size="sm" fw={500}>
Custom Button
</Text>
<Text c="dimmed" size="xs">
Built with UnstyledButton
</Text>
</div>
</Group>
</UnstyledButton>
);
}Specialized close/dismiss button.
interface CloseButtonProps {
/** Close button icon */
icon?: React.ReactNode;
/** Close button size */
size?: MantineSize | number;
/** Close button color */
iconSize?: number;
/** Close button variant */
variant?: 'subtle' | 'transparent';
/** If true, button will be disabled */
disabled?: boolean;
}Usage Example:
import { CloseButton, Group } from '@mantine/core';
function CloseButtonDemo() {
return (
<Group>
<CloseButton aria-label="Close modal" />
<CloseButton size="xl" />
<CloseButton variant="transparent" />
</Group>
);
}Button for copying text to clipboard.
interface CopyButtonProps {
/** Value to copy */
value: string;
/** Copy timeout */
timeout?: number;
/** Render function with copy state */
children: (payload: { copied: boolean; copy: () => void }) => React.ReactNode;
}Usage Example:
import { CopyButton, ActionIcon, Tooltip, rem } from '@mantine/core';
function CopyButtonDemo() {
return (
<CopyButton value="https://mantine.dev" timeout={2000}>
{({ copied, copy }) => (
<Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="right">
<ActionIcon color={copied ? 'teal' : 'gray'} variant="subtle" onClick={copy}>
{copied ? '✓' : '📋'}
</ActionIcon>
</Tooltip>
)}
</CopyButton>
);
}Button for triggering file selection.
interface FileButtonProps {
/** File input onChange handler */
onChange: (file: File | File[] | null) => void;
/** If true, multiple files can be selected */
multiple?: boolean;
/** Accepted file types */
accept?: string;
/** File input name */
name?: string;
/** File input form */
form?: string;
/** If true, button will be disabled */
disabled?: boolean;
/** Capture mode for mobile devices */
capture?: boolean | 'user' | 'environment';
/** Render function */
children: (props: { onClick: () => void }) => React.ReactNode;
/** File input props */
inputProps?: React.ComponentPropsWithoutRef<'input'>;
}Usage Example:
import { FileButton, Button, Group, Text } from '@mantine/core';
import { useState } from 'react';
function FileButtonDemo() {
const [file, setFile] = useState<File | null>(null);
return (
<Group>
<FileButton onChange={setFile} accept="image/png,image/jpeg">
{(props) => <Button {...props}>Upload image</Button>}
</FileButton>
{file && (
<Text size="sm" ta="center" mt="sm">
Picked file: {file.name}
</Text>
)}
</Group>
);
}
// Multiple files
function MultipleFileButton() {
const [files, setFiles] = useState<File[]>([]);
return (
<FileButton onChange={setFiles} accept="image/png,image/jpeg" multiple>
{(props) => <Button {...props}>Upload images</Button>}
</FileButton>
);
}Hamburger menu button with animation.
interface BurgerProps {
/** If true, burger is opened */
opened: boolean;
/** Called when burger is clicked */
onClick?: () => void;
/** Burger color */
color?: string;
/** Burger size */
size?: MantineSize | number;
/** Burger line size */
lineSize?: number;
/** Transition duration */
transitionDuration?: number;
}Usage Example:
import { Burger } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
function BurgerDemo() {
const [opened, { toggle }] = useDisclosure(false);
return (
<Burger
opened={opened}
onClick={toggle}
aria-label={opened ? 'Close navigation' : 'Open navigation'}
/>
);
}Flexible text component with styling options.
interface TextProps {
/** Text children */
children?: React.ReactNode;
/** Text size */
size?: MantineSize | string;
/** Text color */
c?: MantineColor;
/** Text weight */
fw?: React.CSSProperties['fontWeight'];
/** Text style */
fs?: React.CSSProperties['fontStyle'];
/** Text decoration */
td?: React.CSSProperties['textDecoration'];
/** Text transform */
tt?: React.CSSProperties['textTransform'];
/** Text align */
ta?: React.CSSProperties['textAlign'];
/** Line height */
lh?: React.CSSProperties['lineHeight'];
/** If true, text will be truncated with ellipsis */
truncate?: boolean | 'start' | 'end';
/** Number of lines to display */
lineClamp?: number;
/** If true, text will inherit parent color */
inherit?: boolean;
/** If true, text will be displayed as span */
span?: boolean;
/** Text variant */
variant?: 'text' | 'gradient';
/** Text gradient (for gradient variant) */
gradient?: MantineGradient;
}Usage Example:
import { Text, Stack } from '@mantine/core';
function TextDemo() {
return (
<Stack>
<Text>Default text</Text>
<Text size="xs">Extra small text</Text>
<Text size="lg">Large text</Text>
<Text fw={500}>Medium weight text</Text>
<Text fw={700}>Bold text</Text>
<Text fs="italic">Italic text</Text>
<Text td="underline">Underlined text</Text>
<Text c="red">Red text</Text>
<Text c="dimmed">Dimmed text</Text>
<Text tt="uppercase">Uppercase text</Text>
<Text ta="center">Center aligned text</Text>
<Text truncate w={200}>
This text will be truncated if it's too long to fit
</Text>
<Text lineClamp={2}>
This is a long text that will be clamped to 2 lines. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Text>
<Text variant="gradient" gradient={{ from: 'blue', to: 'cyan' }}>
Gradient text
</Text>
</Stack>
);
}Heading component (h1-h6) with size variants.
interface TitleProps {
/** Title children */
children?: React.ReactNode;
/** Title order (1-6) */
order?: 1 | 2 | 3 | 4 | 5 | 6;
/** Title size */
size?: MantineSize | string;
/** Title color */
c?: MantineColor;
/** Title weight */
fw?: React.CSSProperties['fontWeight'];
/** Title style */
fs?: React.CSSProperties['fontStyle'];
/** Title decoration */
td?: React.CSSProperties['textDecoration'];
/** Title transform */
tt?: React.CSSProperties['textTransform'];
/** Title align */
ta?: React.CSSProperties['textAlign'];
/** Line height */
lh?: React.CSSProperties['lineHeight'];
/** If true, title will be truncated */
truncate?: boolean | 'start' | 'end';
/** Number of lines to display */
lineClamp?: number;
}Usage Example:
import { Title, Stack } from '@mantine/core';
function TitleDemo() {
return (
<Stack>
<Title order={1}>H1 Heading</Title>
<Title order={2}>H2 Heading</Title>
<Title order={3}>H3 Heading</Title>
<Title order={4}>H4 Heading</Title>
<Title order={5}>H5 Heading</Title>
<Title order={6}>H6 Heading</Title>
<Title order={1} size="h3">H1 with H3 size</Title>
<Title order={2} c="blue">Blue H2</Title>
<Title order={3} ta="center">Centered H3</Title>
<Title order={4} tt="uppercase">Uppercase H4</Title>
</Stack>
);
}Inline code component with syntax highlighting support.
interface CodeProps {
/** Code children */
children?: React.ReactNode;
/** Code color */
color?: MantineColor;
/** If true, code will be displayed as block */
block?: boolean;
/** Code font size */
fz?: MantineSize | string;
/** Code font weight */
fw?: React.CSSProperties['fontWeight'];
}Usage Example:
import { Code, Text, Stack } from '@mantine/core';
function CodeDemo() {
return (
<Stack>
<Text>
Install package with <Code>npm install @mantine/core</Code> command
</Text>
<Code block>
{`import { Button } from '@mantine/core';
function Demo() {
return <Button>Hello world</Button>;
}`}
</Code>
<Code color="red">Error in code</Code>
<Code color="teal">Success code</Code>
</Stack>
);
}Highlighted text component.
interface MarkProps {
/** Mark children */
children: React.ReactNode;
/** Mark color */
color?: MantineColor;
}Usage Example:
import { Mark, Text } from '@mantine/core';
function MarkDemo() {
return (
<Text>
Highlight <Mark>important parts</Mark> of your content with{' '}
<Mark color="red">different colors</Mark>
</Text>
);
}Blockquote component for quoted content.
interface BlockquoteProps {
/** Blockquote children */
children: React.ReactNode;
/** Blockquote color */
color?: MantineColor;
/** Blockquote radius */
radius?: MantineRadius;
/** Blockquote icon */
icon?: React.ReactNode;
/** Blockquote cite */
cite?: React.ReactNode;
}Usage Example:
import { Blockquote } from '@mantine/core';
function BlockquoteDemo() {
return (
<Blockquote cite="– Forrest Gump">
Life is like a box of chocolates, you never know what you're gonna get
</Blockquote>
);
}
// With icon
function BlockquoteWithIcon() {
return (
<Blockquote color="red" cite="– Someone" icon="💡">
Great ideas come from great minds
</Blockquote>
);
}Text highlighting component with search functionality.
interface HighlightProps {
/** Text to highlight */
children: string;
/** Text to highlight */
highlight: string | string[];
/** Highlight color */
color?: MantineColor;
/** Highlight component */
highlightComponent?: React.ComponentType<any>;
/** Highlight styles */
highlightStyles?: React.CSSProperties | ((theme: MantineTheme) => React.CSSProperties);
}Usage Example:
import { Highlight } from '@mantine/core';
function HighlightDemo() {
return (
<Highlight highlight={['ipsum', 'dolor']}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
</Highlight>
);
}
// Multiple highlights with custom colors
function MultiHighlight() {
return (
<div>
<Highlight highlight="react" color="blue">
React is a JavaScript library for building user interfaces
</Highlight>
<Highlight highlight={['Vue', 'Angular']} color="red">
Vue and Angular are also popular JavaScript frameworks
</Highlight>
</div>
);
}Keyboard key representation component.
interface KbdProps {
/** Kbd children */
children: React.ReactNode;
/** Kbd size */
size?: MantineSize;
}Usage Example:
import { Kbd, Text, Group } from '@mantine/core';
function KbdDemo() {
return (
<div>
<Text>
Press <Kbd>Ctrl</Kbd> + <Kbd>Shift</Kbd> + <Kbd>M</Kbd> to open developer tools
</Text>
<Group mt="md">
<Kbd size="xs">⌘</Kbd>
<Kbd size="sm">Ctrl</Kbd>
<Kbd size="md">Shift</Kbd>
<Kbd size="lg">Alt</Kbd>
<Kbd size="xl">Space</Kbd>
</Group>
</div>
);
}Link component with theme integration.
interface AnchorProps {
/** Anchor children */
children?: React.ReactNode;
/** Anchor href */
href?: string;
/** Anchor target */
target?: string;
/** Anchor type */
type?: 'button' | 'reset' | 'submit';
/** If true, link will be underlined */
underline?: 'always' | 'hover' | 'never';
/** Anchor size */
size?: MantineSize;
/** Anchor color */
c?: MantineColor;
/** Anchor weight */
fw?: React.CSSProperties['fontWeight'];
}Usage Example:
import { Anchor, Text } from '@mantine/core';
function AnchorDemo() {
return (
<Text>
Visit <Anchor href="https://mantine.dev" target="_blank">
Mantine website
</Anchor> for more information. You can also check out our{' '}
<Anchor href="#" underline="always">
always underlined link
</Anchor> or{' '}
<Anchor href="#" underline="never">
never underlined link
</Anchor>.
</Text>
);
}Generic typography component for custom text elements.
interface TypographyProps {
/** Typography children */
children?: React.ReactNode;
/** Typography component to render */
component?: React.ElementType;
/** Typography size */
size?: MantineSize | string;
/** Typography color */
c?: MantineColor;
/** Typography weight */
fw?: React.CSSProperties['fontWeight'];
/** Typography style */
fs?: React.CSSProperties['fontStyle'];
/** Typography decoration */
td?: React.CSSProperties['textDecoration'];
/** Typography transform */
tt?: React.CSSProperties['textTransform'];
/** Typography align */
ta?: React.CSSProperties['textAlign'];
/** Line height */
lh?: React.CSSProperties['lineHeight'];
}Component for formatting and displaying numbers.
interface NumberFormatterProps {
/** Number to format */
value: number;
/** If true, thousand separator will be displayed */
thousandSeparator?: boolean | string;
/** Decimal separator */
decimalSeparator?: string;
/** Number of decimal places */
decimalScale?: number;
/** If true, number will have fixed decimal places */
fixedDecimalScale?: boolean;
/** Number prefix */
prefix?: string;
/** Number suffix */
suffix?: string;
/** Allow negative values */
allowNegative?: boolean;
/** Allow leading zeros */
allowLeadingZeros?: boolean;
}Usage Example:
import { NumberFormatter, Stack } from '@mantine/core';
function NumberFormatterDemo() {
return (
<Stack>
<NumberFormatter value={1000000} thousandSeparator />
<NumberFormatter value={1234.567} decimalScale={2} />
<NumberFormatter value={1234.567} prefix="$" suffix=" USD" />
<NumberFormatter value={1234567.89} thousandSeparator="," decimalSeparator="." />
</Stack>
);
}Button and typography components integrate seamlessly with the Mantine theme system:
import { MantineProvider, Button, Text, Title } from '@mantine/core';
const theme = {
components: {
Button: {
defaultProps: {
variant: 'light',
radius: 'md',
},
},
Text: {
defaultProps: {
size: 'sm',
},
},
Title: {
styles: {
root: {
'&[data-order="1"]': {
fontSize: '2rem',
fontWeight: 700,
},
},
},
},
},
fontSizes: {
xs: '0.75rem',
sm: '0.875rem',
md: '1rem',
lg: '1.125rem',
xl: '1.25rem',
},
fontFamily: 'Inter, sans-serif',
headings: {
fontFamily: 'Inter, sans-serif',
sizes: {
h1: { fontSize: '2rem', lineHeight: '1.2' },
h2: { fontSize: '1.5rem', lineHeight: '1.3' },
h3: { fontSize: '1.25rem', lineHeight: '1.4' },
},
},
};
function App() {
return (
<MantineProvider theme={theme}>
{/* Components will use theme defaults */}
<Title order={1}>Main Heading</Title>
<Text>Regular text content</Text>
<Button>Themed Button</Button>
</MantineProvider>
);
}Button Variations:
import { Button, Group, Stack } from '@mantine/core';
function ButtonShowcase() {
return (
<Stack>
<Group>
<Button variant="filled">Primary</Button>
<Button variant="outline">Secondary</Button>
<Button variant="light">Tertiary</Button>
</Group>
<Group>
<Button size="xs">Extra Small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra Large</Button>
</Group>
<Group>
<Button fullWidth>Full Width Button</Button>
</Group>
</Stack>
);
}Typography Hierarchy:
import { Title, Text, Stack } from '@mantine/core';
function TypographyHierarchy() {
return (
<Stack>
<Title order={1}>Main Page Title</Title>
<Title order={2}>Section Heading</Title>
<Title order={3}>Subsection Heading</Title>
<Text size="lg">Lead paragraph text</Text>
<Text>Regular body text</Text>
<Text size="sm" c="dimmed">Small supplementary text</Text>
</Stack>
);
}Interactive Elements:
import { Button, ActionIcon, Group, Tooltip } from '@mantine/core';
function InteractiveElements() {
return (
<Group>
<Button leftSection="💾">Save</Button>
<Tooltip label="Edit item">
<ActionIcon variant="light">
✏️
</ActionIcon>
</Tooltip>
<Tooltip label="Delete item">
<ActionIcon variant="light" color="red">
🗑️
</ActionIcon>
</Tooltip>
</Group>
);
}Button and typography components include comprehensive accessibility support: