# Styling & Theming Reference Mantine styling: MantineProvider, theme object, CSS modules, style props, and Styles API. ## MantineProvider Required wrapper for all Mantine components: ```tsx import { createTheme, MantineProvider } from '@mantine/core'; const theme = createTheme({ primaryColor: 'blue', fontFamily: 'Inter, sans-serif', }); function App() { return ( {/* App content */} ); } ``` ### Key Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `theme` | `MantineThemeOverride` | - | Theme customization | | `defaultColorScheme` | `'light' \| 'dark' \| 'auto'` | `'light'` | Default color scheme | | `forceColorScheme` | `'light' \| 'dark'` | - | Force specific scheme | | `env` | `'default' \| 'test'` | `'default'` | Disable transitions for tests | ## Theme Object ```tsx import { createTheme, rem } from '@mantine/core'; const theme = createTheme({ // Colors primaryColor: 'blue', primaryShade: { light: 6, dark: 8 }, // Typography fontFamily: 'Inter, sans-serif', headings: { fontFamily: 'Greycliff CF, sans-serif', fontWeight: '700', }, // Spacing & Sizing spacing: { xs: rem(10), sm: rem(12), md: rem(16), lg: rem(20), xl: rem(32) }, radius: { xs: rem(2), sm: rem(4), md: rem(8), lg: rem(16), xl: rem(32) }, // Defaults defaultRadius: 'md', cursorType: 'pointer', respectReducedMotion: true, }); ``` ## Custom Colors ```tsx import { createTheme, MantineColorsTuple } from '@mantine/core'; const brand: MantineColorsTuple = [ '#f0f9ff', '#e0f2fe', '#bae6fd', '#7dd3fc', '#38bdf8', '#0ea5e9', '#0284c7', '#0369a1', '#075985', '#0c4a6e', ]; const theme = createTheme({ colors: { brand }, primaryColor: 'brand', }); ``` ## Color Scheme (Dark Mode) ```tsx import { useMantineColorScheme, useComputedColorScheme } from '@mantine/core'; function ColorSchemeToggle() { const { setColorScheme, toggleColorScheme } = useMantineColorScheme(); const computed = useComputedColorScheme('light'); // Resolved value return ( <> ); } // SSR: Prevent flash of wrong color scheme import { ColorSchemeScript, mantineHtmlProps } from '@mantine/core'; ``` ## Style Props All components accept style props for quick styling: ```tsx import { Box, Text, Button } from '@mantine/core'; function Demo() { return ( Uppercase dimmed text ); } ``` ### Common Style Props | Prop | CSS Property | Example | |------|--------------|---------| | `m`, `mx`, `my`, `mt`, `mr`, `mb`, `ml` | margin | `m="md"`, `mt={20}` | | `p`, `px`, `py`, `pt`, `pr`, `pb`, `pl` | padding | `p="lg"` | | `w`, `h`, `maw`, `mah`, `miw`, `mih` | width, height, max/min | `w="100%"` | | `c` | color | `c="blue.6"`, `c="dimmed"` | | `bg` | background-color | `bg="gray.1"` | | `fz` | font-size | `fz="sm"`, `fz={14}` | | `fw` | font-weight | `fw={500}`, `fw="bold"` | | `ta` | text-align | `ta="center"` | | `td` | text-decoration | `td="underline"` | | `tt` | text-transform | `tt="uppercase"` | | `ff` | font-family | `ff="monospace"` | | `lh` | line-height | `lh={1.5}` | | `pos` | position | `pos="absolute"` | | `top`, `left`, `right`, `bottom` | position offsets | `top={10}` | | `display` | display | `display="flex"` | | `opacity` | opacity | `opacity={0.5}` | ### Responsive Props ```tsx Responsive box ``` ## CSS Modules Recommended styling approach. Create `.module.css` files: ```css /* Button.module.css */ .root { background-color: var(--mantine-color-blue-6); @mixin hover { background-color: var(--mantine-color-blue-7); } /* Responsive */ @mixin smaller-than sm { font-size: var(--mantine-font-size-xs); } @mixin larger-than md { padding: var(--mantine-spacing-xl); } /* Dark mode */ @mixin dark { background-color: var(--mantine-color-blue-8); } @mixin light { background-color: var(--mantine-color-blue-4); } } .label { color: var(--mantine-color-white); } ``` ```tsx import { Button } from '@mantine/core'; import classes from './Button.module.css'; function Demo() { return ( ); } ``` ## PostCSS Preset `postcss-preset-mantine` provides: ### Mixins ```css /* Hover state */ @mixin hover { /* Hover-only styles */ } /* Responsive breakpoints */ @mixin smaller-than sm { } @mixin larger-than md { } /* Color scheme */ @mixin light { } @mixin dark { } /* RTL support */ @mixin rtl { } @mixin ltr { } ``` ### Functions ```css .element { /* rem() - convert to rem */ font-size: rem(16px); /* 1rem */ /* em() - convert to em */ padding: em(24px); /* 1.5em */ /* light-dark() - color scheme values */ background: light-dark(white, black); /* alpha() - add opacity to color */ background: alpha(var(--mantine-color-blue-5), 0.5); } ``` ## Styles API Override internal component styles: ### classNames Prop ```tsx import { TextInput } from '@mantine/core'; import classes from './TextInput.module.css'; // CSS module with selectors matching Styles API // .root, .input, .label, .error, etc. ``` ### styles Prop (CSS-in-JS) ```tsx ``` ### styles Function ```tsx ({ input: { borderColor: props.error ? theme.colors.red[6] : theme.colors.gray[4], }, })} /> ``` ### Finding Selectors All Styles API selectors are documented for each component. Common patterns: - `root` - Root element - `label` - Label text - `input` - Input element - `wrapper` - Input wrapper - `error` - Error message - `description` - Description text - `required` - Required asterisk - `section` - Input sections (left/right icons) ## hiddenFrom / visibleFrom Hide/show at breakpoints: ```tsx import { Text } from '@mantine/core'; Hidden on sm and larger Visible only on md and larger ``` ## lightHidden / darkHidden Hide based on color scheme: ```tsx Only in dark mode Only in light mode ``` ## Box Component Base component for custom styling: ```tsx import { Box } from '@mantine/core'; Content ``` ## Polymorphic Components Many components accept `component` prop: ```tsx import { Button } from '@mantine/core'; import { Link } from 'react-router-dom'; // Render Button as Link // Render as native anchor ``` ## CSS Variables in Styles Access theme values: ```tsx Styled with CSS variables ``` ## Global Styles ```tsx // In your CSS :root { --my-custom-color: #ff6b6b; } /* Target Mantine root element */ [data-mantine-color-scheme="dark"] { --my-custom-color: #ff8787; } /* Global component overrides */ .mantine-Button-root { font-weight: 600; } ``` ## rem() and em() Utilities ```tsx import { rem, em } from '@mantine/core'; // In styles or inline // rem(16) => '1rem' // em(24) => '1.5em' ``` ## Style Props vs CSS Modules | Use Case | Recommended | |----------|-------------| | Quick prototyping | Style props | | Simple spacing/colors | Style props | | Complex hover/focus states | CSS modules | | Responsive layouts | CSS modules | | Reusable component styles | CSS modules | | Performance critical | CSS modules | ## Component Default Props (Theme) Override defaults globally: ```tsx const theme = createTheme({ components: { Button: Button.extend({ defaultProps: { variant: 'outline', size: 'md', radius: 'xl' }, }), TextInput: TextInput.extend({ defaultProps: { size: 'md' }, classNames: { root: 'my-input-root', input: 'my-input' }, }), }, }); ``` ## CSS Variables Reference ``` --mantine-color-{color}-{shade} // Colors (0-9) --mantine-primary-color-{shade} // Primary color --mantine-spacing-{size} // xs, sm, md, lg, xl --mantine-radius-{size} // xs, sm, md, lg, xl --mantine-font-family // Main font --mantine-font-size-{size} // xs, sm, md, lg, xl --mantine-breakpoint-{size} // Responsive breakpoints ```