Справочник по Mantine 9 с нативной таблицей участников и боковой панелью планирования. Изучите настоящие шкалы темы, подключите useForm к TextInput, Select, Checkbox и DatePickerInput и проверьте валидацию перед добавлением локальной записи.
Нативное ядро Mantine 9.6.3, пакеты form и dates, а также React 19. Принудительно включены светлое оформление и тема с бирюзовым акцентом; используются только локальные данные. · Справочник по реализации
02
Справочник по дизайн-системе Mantine
Проверенные значения DEFAULT_THEME из @mantine/core 9.6.3. Эквивалентные значения в пикселях рассчитаны при корневом размере 16px и theme.scale=1; масштабируемые токены задаются через --mantine-scale. Бирюзовый основной цвет, оттенок 8 и радиус md — явные переопределения приложения.
В примере core используется для интерфейса, form — для проверки и привязки полей, а dates — для поля календаря. Переопределения createTheme передаются в MantineProvider. Импортируются и Core CSS, и dates CSS: одного компонента React недостаточно, чтобы воссоздать стилизованный календарь.
Тема выбирает циановый цвет с primaryShade 8 и defaultRadius md. Button.extend задаёт маленькие кнопки по умолчанию для приложения, а TextInput.extend выбирает элементы управления среднего размера. Это намеренно выбранные настройки, показанные в исходном коде, а не утверждение, что каждый продукт Mantine должен их использовать.
Дизайн-система Mantine: используйте индексы палитры и разрешённые роли цветов
Упорядоченная палитра — не набор несвязанных образцов
Цвета Mantine представлены массивами оттенков с индексами. В этом примере используется cyan: cyan.0 — для сдержанной панели сводки, cyan.9 — для акцентного текста, а настроенный основной оттенок — для залитых действий. В справочнике приведена вся шкала cyan, используемая в этой теме.
Для подтверждённого состояния в таблице используется светлый вариант бирюзового, а для отозванного — оранжевый. Рядом с цветом всегда указан текст статуса. При отзыве меняется состояние согласия, но предыдущий сеанс остаётся видимым, чтобы смена цвета незаметно не скрывала историю.
В свойстве color компонента можно указать название палитры; если отдельно задать фоновый цвет в формате hexadecimal, часть решений для вариантов оформления будет обходиться. При использовании обычного CSS предпочтительнее применять сгенерированные переменные для повторяющихся решений темы. В примере сопоставление с переменными CSS показывает, какие значения по-прежнему связаны со шкалой и основным цветом.
Дизайн-система Mantine: примените экспортированный шрифт и шкалы заголовков
Воспроизведите иерархию
Для имён и названий исследований в таблице используется размер текста sm, а для идентификаторов и дат — xs. Порядок заголовка Title order={1} соответствует шкале h1; у панели выдвижения семантический заголовок h2 отображается с размером size="h3", чтобы визуально он был компактнее. Эти решения не зависят от метки и вспомогательного текста, заданных компонентам ввода.
Стек системных шрифтов Mantine не требует загрузки шрифтов с удалённого сервера. Масштабируемые значения шрифтов учитывают --mantine-scale; пиксельные значения в примере рассчитаны для масштаба 1. Не считайте соответствующие им значения в пикселях неизменными, если приложение использует другой масштаб.
Привяжите useForm к реальным компонентам ввода дизайн-системы Mantine
Валидация относится к модели формы
initialValues содержит имя, исследование, дату с допустимым значением null и логическое значение согласия. Функция validate возвращает текст ошибки или null для полей имени, даты и согласия. form.onSubmit запускает эту проверку перед добавлением строки в локальный список. Отдельно создавать вручную отображаемые подписи ошибок не нужно.
TextInput и DatePickerInput получают getInputProps с путём к соответствующему полю. Для Checkbox дополнительно задаётся type:"checkbox", чтобы корректно привязать значение checked. Select использует фиксированный список исследований и allowDeselect={false}; этот сценарий не допускает пустого значения исследования.
Плотность элементов управления и переполнение на границе компонента в дизайн-системе Mantine
Разместите таблицу в собственной прокручиваемой области
Table.ScrollContainer использует minWidth={580}, чтобы на узких экранах все четыре столбца оставались читаемыми. Документ целиком помещается в область просмотра; при необходимости по горизонтали прокручивается только область с данными. Значения horizontalSpacing="lg" и verticalSpacing="md" используют интервалы темы, а не независимые отступы ячеек.
Для трёх сводных карточек используется SimpleGrid с одним столбцом по умолчанию и тремя столбцами начиная с sm. Внутренний отступ страницы аналогично меняется с md на xl. Это адаптивные объекты стилей, а минимальная ширина таблицы — явное решение, обусловленное содержимым.
Различайте недействительную запись на исследование и отзыв согласия в дизайн-системе Mantine
В примере предусмотрены две разные операции изменения данных
Форма записи не добавит строку, пока имя, дата сеанса и согласие в примере не пройдут проверку. После успешного добавления запись закрывается, одна запись добавляется в список, а сводные счётчики обновляются. В уведомлении сказано, что данные исследования не сохранялись.
Отзыв согласия меняет только статус выбранной строки и отключает действие для неё. Дата остаётся видимой как история, а число запланированных сеансов не учитывает строки с отозванным согласием. Это оговорённая политика демонстрационного примера, а не реальное правило хранения данных исследования.
Недействительная форма: покажите ошибки у полей и оставьте панель открытой.
Локальная запись принята: добавьте строку один раз и сбросьте черновик для следующей записи.
Согласие в примере отозвано: сохраните запись и отключите повторный отзыв.
Согласованная работа панели выдвижения и семантики полей ввода в дизайн-системе Mantine
Фокус и метки
Панели выдвижения передаётся заголовок, а управление фокусом обеспечивает сам компонент. Для поля имени задан атрибут data-autofocus. У каждого элемента формы есть видимая метка; сообщения проверки передаются через связанное свойство error. Доступное имя кнопки отзыва содержит имя участника, поэтому несколько одинаковых видимых надписей можно различить.
В этом примере закрытие панели отменяет черновик: при открытии панели «Добавить участника» форма сбрасывается. Календарь — нативное всплывающее окно Mantine внутри панели. Проверяйте работу с клавиатурой вместе с окружающим ограничением фокуса, а не считайте, что два компонента с доступной реализацией обязательно будут корректно работать вместе.
Установите пакеты согласованных версий и подключите обе таблицы стилей в дизайн-системе Mantine
Полная конфигурация приведена здесь
Выполните приведённые ниже команды в терминале, замените содержимое App.jsx полной композицией и подключите её с помощью предоставленного main.jsx. Версии четырёх пакетов Mantine намеренно согласованы. В App.jsx содержатся провайдер и тема, поэтому отдельный скрытый файл провайдера не нужен.
Не копируйте пример с датой из другой мажорной версии, не проверив тип её значения. Согласуйте начальную дату формы и её валидацию с фактическим DatePickerInput API. Этот пример создан для указанных версий пакетов, а не выведен из старого руководства.
Подключите core/styles.css и dates/styles.css один раз на уровне приложения.
Запустите форму, добавьте запись с датой, затем проверьте таблицу и результат отзыва согласия.
Проверьте календарь, форму и таблицу как единое целое в дизайн-системе Mantine
Что проверить
Отправьте пустую форму в панели, чтобы увидеть ошибки для имени, даты и согласия. Введите имя, выберите день в календаре и подтвердите согласие в примере, затем отправьте форму ещё раз. Новый участник должен появиться с выбранной датой и неизменным демонстрационным идентификатором. Затем отзовите согласие этого участника и проверьте изменения в строке и сводной информации.
Модель данных намеренно проста и хранится только в памяти. Здесь нет набора участников исследования, сбора согласий, сохранения данных на сервере или преобразования часовых поясов. Практическая ценность этого примера — в интеграции нативных пакетов и наглядном поведении элементов управления, а не в подразумеваемой серверной части для управления исследованиями.
Примеры компонентов дизайн-системы Mantine
App.jsx — провайдер, тема, таблица и панель записи
Полный пример с нативными компонентами Mantine. Содержит переопределения темы, валидацию useForm, DatePickerInput, обновление таблицы и изменение статуса согласия.
jsx
import React, {useState} from 'react';
import {MantineProvider, createTheme, Box, Group, Stack, Title, Text, Button, Paper, Badge, Table, Drawer, TextInput, Select, Checkbox, Alert, SimpleGrid} from '@mantine/core';
import {useForm} from '@mantine/form';
import {DatePickerInput} from '@mantine/dates';
import '@mantine/core/styles.css';
import '@mantine/dates/styles.css';
const theme=createTheme({primaryColor:'cyan',primaryShade:8,defaultRadius:'md',components:{Button:Button.extend({defaultProps:{size:'sm'}}),TextInput:TextInput.extend({defaultProps:{size:'md'}})}});
function Tracker(){
const[opened,setOpened]=useState(false),[notice,setNotice]=useState(''),[rows,setRows]=useState([{name:'Alex Morgan',study:'Navigation study',date:'2026-10-14',status:'Confirmed'},{name:'Sam Rivera',study:'Editor study',date:'2026-10-16',status:'Confirmed'}]);
const form=useForm({initialValues:{name:'',study:'Navigation study',date:null,consent:false},validate:{name:v=>v.trim().length<2?'Enter a name with at least two characters.':null,date:v=>!v?'Choose a session date.':null,consent:v=>!v?'Confirm consent before scheduling this example.':null}});
const submit=values=>{setRows([...rows,{name:values.name.trim(),study:values.study,date:values.date,status:'Confirmed'}]);setOpened(false);setNotice('Participant added in this browser only. No research record was stored.');form.reset();};
return <Box p={{base:'md',sm:'xl'}} bg='gray.0'><Box maw={1040} mx='auto'>
<Group justify='space-between' align='flex-start' mb='xl'><Box><Text c='cyan.9' fw={700} size='xs' tt='uppercase' mb='xs'>Mantine · Research operations</Text><Title order={1}>Participant sessions</Title><Text c='dimmed' mt='xs'>Consent and scheduling stay visible in the same working view.</Text></Box><Button onClick={()=>{form.reset();setOpened(true)}}>Add participant</Button></Group>
<SimpleGrid cols={{base:1,sm:3}} mb='xl'><Paper withBorder p='lg'><Text size='sm' c='dimmed'>In this preview</Text><Text fz={32} fw={700}>{rows.length}</Text><Text size='sm'>Participant records</Text></Paper><Paper withBorder p='lg'><Text size='sm' c='dimmed'>Scheduled</Text><Text fz={32} fw={700}>{rows.filter(r=>r.status==='Confirmed').length}</Text><Text size='sm'>With confirmed example consent</Text></Paper><Paper withBorder p='lg' bg='cyan.0'><Text size='sm' c='cyan.9' fw={600}>Working theme</Text><Text mt='xs' size='sm'>cyan.8 action · radius md<br/>spacing lg · body md</Text></Paper></SimpleGrid>
{notice&&<Alert title='Local change' color='cyan' mb='md' withCloseButton onClose={()=>setNotice('')}>{notice}</Alert>}
<Paper withBorder radius='md'><Table.ScrollContainer minWidth={580}><Table verticalSpacing='md' horizontalSpacing='lg' highlightOnHover><Table.Thead><Table.Tr><Table.Th>Participant</Table.Th><Table.Th>Study / session</Table.Th><Table.Th>Consent</Table.Th><Table.Th>Action</Table.Th></Table.Tr></Table.Thead><Table.Tbody>{rows.map((r,i)=><Table.Tr key={i}><Table.Td><Text fw={600} size='sm'>{r.name}</Text><Text size='xs' c='dimmed'>P-{String(i+1).padStart(3,'0')}</Text></Table.Td><Table.Td><Text size='sm'>{r.study}</Text><Text size='xs' c='dimmed'>{r.date}</Text></Table.Td><Table.Td><Badge variant='light' color={r.status==='Confirmed'?'cyan':'orange'}>{r.status}</Badge></Table.Td><Table.Td><Button variant='subtle' color='gray' disabled={r.status==='Withdrawn'} aria-label={'Withdraw consent for '+r.name} onClick={()=>{setRows(rows.map((x,j)=>j===i?{...x,status:'Withdrawn'}:x));setNotice('Consent withdrawn in the preview. The prior session remains visible as history.')}}>Withdraw</Button></Table.Td></Table.Tr>)}</Table.Tbody></Table></Table.ScrollContainer></Paper>
<Text size='xs' c='dimmed' mt='lg'>Native Mantine 9.6.3: Table, Drawer, useForm, DatePickerInput, and input error styles. All records are memory-only examples.</Text>
<Drawer opened={opened} onClose={()=>setOpened(false)} position='right' size='md' title={<Title order={2} size='h3'>Schedule a participant</Title>}><form onSubmit={form.onSubmit(submit)} noValidate><Stack gap='lg'><Text size='sm' c='dimmed'>All fields below belong to this one study enrollment. Closing discards the draft.</Text><TextInput label='Participant name' placeholder='Jules Davis' data-autofocus {...form.getInputProps('name')}/><Select label='Study' data={['Navigation study','Editor study']} allowDeselect={false} {...form.getInputProps('study')}/><DatePickerInput label='Session date' placeholder='Choose a date' valueFormat='DD MMM YYYY' defaultDate='2026-10-01' {...form.getInputProps('date')}/><Checkbox label='Consent is confirmed for this example study' {...form.getInputProps('consent',{type:'checkbox'})}/><Button type='submit'>Add to preview</Button><Text size='xs' c='dimmed'>This checkbox demonstrates validation; it is not a research consent collection process.</Text></Stack></form></Drawer>
</Box></Box>;
}
export default function App(){return <MantineProvider theme={theme} forceColorScheme='light'><Tracker/></MantineProvider>}
Флажок согласия используется как условие валидации в примере, а не как часть реального процесса сбора согласий.
04
Настройка ИИ-агента для дизайн-системы Mantine
Отправная точка для реализации
Используйте выпуск Node, поддерживаемый выбранным шаблоном Vite. Исходный код содержит импорты провайдера, темы и таблиц стилей; для показанного сценария не требуется ни серверная часть, ни собственный CSS.
текст
# Terminal
npm create vite@latest participant-demo -- --template react
cd participant-demo
npm install
npm install @mantine/[email protected] @mantine/[email protected] @mantine/[email protected] @mantine/[email protected] dayjs
# Save the complete example as src/App.jsx.
# Replace src/main.jsx with:
import React from 'react';
import {createRoot} from 'react-dom/client';
import App from './App';
createRoot(document.getElementById('root')).render(<App/>);
# Terminal
npm run dev
Запрос для вашего проекта
Промпт для AI-агента
Используйте предоставленную композицию Mantine 9.6.3 и согласуйте версии core, form и dates. Сохраните провайдер, оба импорта CSS, привязки getInputProps, тип значения даты и границу прокрутки таблицы. Заменяйте локальные изменения записей на реальный сервис только после определения правил согласия и хранения данных. Не смешивайте отзыв согласия с удалением записи; сообщения об ошибках ввода должны оставаться читаемыми, а фокус панели — корректно управляться.
05
Источники и область применения дизайн-системы Mantine
Исходный пример OpenDesign на основе Mantine 9.6.3. Значения темы по умолчанию отделены от переопределений приложения для cyan и формы. Нативный пример демонстрирует только локальные записи и валидацию: он не собирает согласия и не сохраняет данные исследования.