--- 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'; ); } ``` **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); ); } ``` **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 Title Content ``` ### 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