Гибкие методы стилизации компонентов Mantine
Содержание
Ранее на уроках этого курса мы разобрались с темой и цветовыми схемами. Теперь пришло время самого важного — как применять стили к компонентам. Mantine предлагает несколько подходов, и у каждого есть свои сценарии использования. В этом уроке мы пройдем все способы — от самых быстрых до самых мощных и производительных. Главное правило, которое стоит запомнить: CSS-модули — это рекомендуемый способ для большинства случаев.
Компонентные пропсы — самый простой способ
У каждого компонента есть набор пропсов, которые управляют его внешностью. Например, у Button это color, variant, size и radius.
import { Button, Group } from '@mantine/core';
function Demo() {
return (
<Group>
<Button variant="filled" color="blue" size="sm" radius="md">
Синяя кнопка
</Button>
<Button variant="outline" color="red" size="lg" radius="xl">
Красная outline
</Button>
<Button variant="subtle" color="green" size="xs" radius="xs">
Зеленая subtle
</Button>
</Group>
);
}
Когда использовать: для базовой стилизации без создания дополнительных файлов. Это самый оптимальный способ кастомизации в большинстве случаев, потому что пропсы управляют сразу несколькими CSS-свойствами.
Стилевые пропсы (Style Props) — для быстрых правок
Стилевые пропсы работают как обычные пропсы, но есть важное отличие: они всегда управляют только одним CSS-свойством. Например, пропс c управляет цветом текста, а bg — фоном. Эти пропсы доступны для любого компонента Mantine.
import { Text, Paper, TextInput, Button } from '@mantine/core';
function Demo() {
return (
<>
{/* Управляем цветом и размером текста */}
<Text c="blue.8" fz="lg" fw={700}>
Крупный синий текст
</Text>
<Text c="dimmed" fz="sm">
Приглушенный мелкий текст
</Text>
{/* Отступы и фон */}
<Paper p="xl" bg="gray.1" mt="md" radius="md">
<Text>Бумага с отступами</Text>
</Paper>
{/* Поля у инпутов в форме */}
<TextInput label="Имя" />
<TextInput label="Фамилия" mt="md" />
<TextInput label="Email" mt="md" />
{/* Размеры и позиционирование */}
<Button w={200} mt="lg" ta="center">
Кнопка шириной 200px
</Button>
</>
);
}
Важно: стилевые пропсы не предназначены для первичной стилизации компонентов. Если вы используете более 3-4 стилевых пропсов на один компонент, лучше вынести стили в отдельный файл — это упростит поддержку и будет производительнее.
Проп style — для CSS-переменных и одноразовых правок
Проп style работает так же, как React-проп style, но поддерживает CSS-переменные. Он полезен в двух случаях:
import { Button, Box, Flex } from '@mantine/core';
function Demo({ color }: { color: string }) {
return (
<Flex gap="md">
{/* Применяем одно CSS-свойство */}
<Button style={{ flex: 1 }}>Растянутая кнопка</Button>
<Button>Обычная кнопка</Button>
{/* Устанавливаем CSS-переменную на основе пропса */}
<Box style={{ '--my-color': color }} c="var(--my-color)">
Текст с динамическим цветом
</Box>
</Flex>
);
}
Когда использовать: для одноразовых правок или когда нужно динамически установить CSS-переменную. Не рекомендуется как основной способ стилизации.
CSS-модули — рекомендованный способ
CSS-модули — это самый производительный и гибкий способ стилизации в Mantine. Они позволяют писать обычный CSS в отдельных файлах, при этом имена классов автоматически локализуются (избегая конфликтов).
Создайте файл Demo.module.css:
/* Demo.module.css */
.root {
padding: 20px;
border-radius: 8px;
background-color: #f8f9fa;
}
.root[data-collapsed] {
padding: 10px;
background-color: #e9ecef;
}
.label {
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
/* Стилизация дочерних элементов */
.root[data-collapsed] .control {
max-width: 40px;
}
.control {
transition: max-width 0.3s ease;
}
А теперь используйте в компоненте:
import { useState } from 'react';
import { Box, Button, Text } from '@mantine/core';
import classes from './Demo.module.css';
function Demo() {
const [collapsed, setCollapsed] = useState(false);
return (
<Box
className={classes.root}
data-collapsed={collapsed || undefined}
>
<Text className={classes.label}>Заголовок</Text>
<Button
className={classes.control}
onClick={() => setCollapsed(!collapsed)}
>
{collapsed ? 'Развернуть' : 'Свернуть'}
</Button>
</Box>
);
}
CSS-модули работают отлично с TypeScript, обеспечивая автодополнение для классов. Это рекомендуемый способ для основной стилизации.
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Styles API — для тонкой настройки внутренних элементов
Самая мощная техника — Styles API. Она позволяет стилизовать любой внутренний элемент компонента, обращаясь к нему по имени (селектору) . У каждого компонента есть документация со списком селекторов — например, у Button есть root, loader, inner, section, label.
import { Button, TextInput } from '@mantine/core';
import classes from './Demo.module.css'; // с CSS-модулями
function Demo() {
return (
<>
{/* Стилизация через classNames (с CSS-модулями) */}
<Button
classNames={{
root: classes.buttonRoot,
label: classes.buttonLabel,
inner: classes.buttonInner,
}}
>
Стилизованная кнопка
</Button>
{/* Стилизация через styles (inline-стили) */}
<Button
styles={{
root: { backgroundColor: 'purple', border: '2px solid darkviolet' },
label: { color: 'white', fontWeight: 700 },
inner: { gap: '8px' },
}}
>
Inline-стили
</Button>
{/* Текстовое поле с кастомным лейблом */}
<TextInput
label="Email"
classNames={{
root: classes.inputRoot,
input: classes.inputField,
label: classes.inputLabel,
}}
/>
</>
);
}
Глобальная настройка через тему
Если вы хотите применить стили ко всем компонентам определенного типа, используйте theme.components:
import { createTheme, MantineProvider } from '@mantine/core';
import classes from './Button.module.css';
const theme = createTheme({
components: {
Button: Button.extend({
classNames: {
root: classes.globalButtonRoot,
label: classes.globalButtonLabel,
},
}),
TextInput: TextInput.extend({
classNames: {
root: classes.inputRoot,
input: classes.inputField,
},
}),
},
});
function App() {
return (
<MantineProvider theme={theme}>
{/* Все Button будут использовать глобальные стили */}
<Button>Стилизован через тему</Button>
</MantineProvider>
);
}
Кастомные варианты и размеры (V9)
В Mantine 9 вы можете добавлять свои варианты (значения пропса variant) и размеры через data- атрибуты или CSS-переменные.
// Добавляем кастомный вариант через CSS
import { Button } from '@mantine/core';
import classes from './Demo.module.css';
function Demo() {
return (
<Button variant="underline" className={classes.underlineButton}>
Подчеркнутая кнопка
</Button>
);
}
/* Demo.module.css */
.underlineButton[data-variant="underline"] {
background: transparent;
border-bottom: 2px solid blue;
border-radius: 0;
padding: 4px 0;
color: blue;
&:hover {
border-bottom-color: darkblue;
color: darkblue;
}
}
Для добавления кастомных размеров используйте CSS-переменные:
/* В CSS-модуле */
.root {
--button-height-xxl: 80px;
--button-padding-x-xxl: 48px;
--button-fz-xxl: 24px;
}
.root[data-size="xxl"] {
height: var(--button-height-xxl);
padding-inline: var(--button-padding-x-xxl);
font-size: var(--button-fz-xxl);
}
Сравнение подходов
| Подход | Сложность | Производительность | Гибкость | Когда использовать |
|---|---|---|---|---|
| Компонентные пропсы | ⭐ | Высокая | Средняя | 80% случаев |
| Стилевые пропсы | ⭐ | Средняя | Низкая | Быстрые правки (до 3-4 пропсов) |
style |
⭐⭐ | Средняя | Низкая | CSS-переменные, одноразовые правки |
| CSS-модули | ⭐⭐⭐ | Высокая | Высокая | Основной способ |
Styles API (classNames) |
⭐⭐⭐⭐ | Высокая | Очень высокая | Тонкая настройка внутренних элементов |
| Styles API (глобально) | ⭐⭐⭐⭐ | Высокая | Очень высокая | Единый стиль для всех компонентов типа |
Итоги
Сегодня вы узнали о шести способах стилизации в Mantine:
- Компонентные пропсы — для базовой стилизации
- Стилевые пропсы (
c,p,m,bg) — для быстрых правок - Проп
style— для CSS-переменных - CSS-модули — основной, наиболее производительный способ
- Styles API — для доступа к внутренним элементам компонентов
- Кастомные варианты — для расширения
variantиsizeв V9
Что должно быть в вашем проекте после этого урока:
- Вы понимаете разницу между компонентными пропсами и стилевыми пропсами
- Вы создали хотя бы один CSS-модуль для стилизации компонента
- Вы использовали
classNamesилиstylesдля настройки внутренних элементов - Вы знаете, как добавить кастомный вариант через
data-variant
В следующем уроке мы перейдем к практике — создадим полноценную форму с валидацией с использованием @mantine/form. Это один из самых мощных инструментов библиотеки!