---
name: mantine-developing
description: Build React UIs with Mantine component library. Customize styles with Styles API, handle forms with @mantine/form, implement theming, and avoid accessibility pitfalls. Use when creating Mantine components or fixing styling issues.
version: 1.0.0
---
# Mantine UI Development
## Purpose
Build React UIs with Mantine's component library, Styles API for customization, and @mantine/form for form handling.
## When NOT to Use
- Basic React development (Claude knows this)
- Non-Mantine UI libraries (Material UI, Chakra, etc.)
- Simple HTML/CSS without Mantine
- Mantine v6 or earlier (this skill covers v7+)
## Quick Start
### Step 1: Import Components
```tsx
// Core components
import { Button, TextInput, Select, Modal } from '@mantine/core';
// Hooks
import { useDisclosure, useToggle } from '@mantine/hooks';
// Form handling
import { useForm } from '@mantine/form';
```
### Step 2: Basic Component Usage
```tsx
```
### Step 3: Customize with Styles API
See [Core Patterns](#core-patterns) below.
### Step 4: Validate Accessibility
- Add `aria-label` to icon-only buttons
- Check keyboard navigation works
- Verify focus states are visible
## Core Patterns
### Styles API (Critical)
Mantine components have multiple inner elements. Use Styles API to target them:
```tsx
// Option 1: classNames prop (recommended for CSS modules)
import classes from './Button.module.css';
```
```css
/* Button.module.css */
.button {
background: linear-gradient(45deg, blue, purple);
}
.buttonLabel {
font-weight: 700;
}
```
```tsx
// Option 2: styles prop (inline styles for inner elements)
// Option 3: CSS variables
// Option 4: Data attributes for state
```
**Finding selector names:** Check Mantine docs for each component's "Styles API" section listing available selectors.
### Form Handling (@mantine/form)
```tsx
import { useForm } from '@mantine/form';
import { TextInput, Checkbox, Button, Box } from '@mantine/core';
function LoginForm() {
const form = useForm({
initialValues: {
email: '',
password: '',
rememberMe: false,
},
validate: {
email: (value) =>
/^\S+@\S+$/.test(value) ? null : 'Invalid email',
password: (value) =>
value.length >= 8 ? null : 'Password must be 8+ characters',
},
// Optional: validate on change instead of only on submit
validateInputOnChange: true,
});
const handleSubmit = (values: typeof form.values) => {
console.log('Form submitted:', values);
};
return (
);
}
```
**Key form methods:**
- `form.getInputProps('fieldName')` - Binds value, onChange, error
- `form.getInputProps('field', { type: 'checkbox' })` - For checkboxes/switches
- `form.onSubmit(handler)` - Validates before calling handler
- `form.setFieldValue('field', value)` - Programmatic updates
- `form.reset()` - Reset to initial values
- `form.validate()` - Manual validation
### Polymorphic Components
Change the underlying HTML element:
```tsx
// Button as link
// Text as span (default is p)
Inline text
// Card as article
Content
```
**TypeScript note:** Ref type changes with component prop!
```tsx
// Default: HTMLButtonElement
const buttonRef = useRef(null);
// With component="a": HTMLAnchorElement
const linkRef = useRef(null);
```
### Theming
```tsx
import { MantineProvider, createTheme } from '@mantine/core';
const theme = createTheme({
primaryColor: 'violet',
colors: {
// Add custom color palette
brand: [
'#f0e6ff', '#d9c2ff', '#c29dff', '#ab79ff',
'#9454ff', '#7d30ff', '#660bff', '#5200d9',
'#3e00a6', '#2b0073'
],
},
components: {
Button: {
defaultProps: {
radius: 'md',
},
},
},
});
function App() {
return (
{/* Your app */}
);
}
```
### Dark Mode
```tsx
import { useMantineColorScheme, Button } from '@mantine/core';
function ColorSchemeToggle() {
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
return (
);
}
```
**CSS for dark mode:**
```css
/* Use light-dark() function */
.myComponent {
background: light-dark(white, var(--mantine-color-dark-7));
color: light-dark(black, white);
}
```
## Common Pitfalls
### 1. Nested Interactive Elements
**Wrong:**
```tsx
{/* Invalid! */}
```
**Correct:**
```tsx
TitleContent
```
### 2. Tooltip on Disabled Button
**Wrong:**
```tsx
{/* Tooltip won't show! */}
```
**Correct:**
```tsx
```
### 3. ActionIcon.Group Wrapping
**Wrong:**
```tsx
{/* Invalid wrapper! */}
```
**Correct:**
```tsx
```
### 4. Missing aria-label
**Wrong:**
```tsx
{/* No accessible name! */}
```
**Correct:**
```tsx
```
### 5. AspectRatio in Flexbox
**Wrong:**
```tsx
{/* Won't size correctly */}
```
**Correct:**
```tsx
{/* Explicit width */}
```
### 6. Select vs Autocomplete Confusion
- **Select**: User MUST choose from options (enforces list)
- **Autocomplete**: User CAN type any value (suggestions only)
```tsx
// Use Select when value must be from list
// Use Autocomplete when free text is acceptable
```
## Accessibility Requirements
1. **Icon buttons must have aria-label:**
```tsx
```
2. **Use closeButtonLabel prop:**
```tsx
```
3. **Set heading order for accordions:**
```tsx
{/* Renders as
*/}
```
4. **Test keyboard navigation:**
- Tab through form fields
- Enter/Space on buttons
- Escape to close modals
- Arrow keys in menus
## Troubleshooting
| Problem | Cause | Solution |
|---------|-------|----------|
| Styles not applying | Wrong selector name | Check component's Styles API docs for available selectors |
| Dark mode has wrong colors | Hardcoded color values | Use `light-dark()` CSS function or theme colors |
| Form not validating | Wrong config | Use `validate` for submit-time, `validateInputOnChange` for live validation |
| TypeScript ref errors | Polymorphic component | Update ref type to match `component` prop value |
| Component won't accept custom props | Polymorphic typing | Props don't extend default element; use `component` to change |
| Tooltip not showing on disabled | Disabled blocks events | Use `data-disabled` with `onClick` preventDefault |
## External Documentation
For latest Mantine documentation:
1. **Context7** (recommended):
```
mcp__context7__get-library-docs
context7CompatibleLibraryID: "/mantinedev/mantine"
topic: "Button" or "Select" or "form" etc.
```
2. **Direct fetch**:
```
WebFetch → https://mantine.dev/llms.txt
```
3. **Official docs**: https://mantine.dev
## Component Quick Reference
See REFERENCE.md for detailed component patterns including:
- Layout: Stack, Group, Grid, Flex, Container, AppShell
- Inputs: TextInput, Select, Checkbox, DatePicker
- Feedback: Modal, Notifications, Alert
- Navigation: Tabs, NavLink, Breadcrumbs
- Data: Table, Skeleton, Timeline
---
## Related Agent
For comprehensive React + Mantine UI guidance that coordinates this and other Mantine skills, use the **`mantine-ui-expert`** agent.
**Cost Optimization:** Use `model="haiku"` when invoking this agent for routine component development tasks. Haiku is sufficient for template-based Mantine patterns and Styles API usage.