主题化组件系统 · 新资源

Mantine 设计系统.

以原生参与者表格和排期抽屉为核心的 Mantine 9 参考示例。查看实际主题比例,将 useForm 连接到 TextInput、Select、Checkbox 和 DatePickerInput,并在添加本地记录前试用验证功能。

OpenDesign 指南9 个章节32 个参考条目原始应用指南
01

Mantine 设计系统界面预览

打开抽屉,触发字段验证,选择研究项目和日期,添加本地参与者,并撤回示例中的知情同意。

参与者表格和排期抽屉打开完整示例
使用原生 Mantine 9.6.3 core、form 和 dates 包,以及 React 19。强制使用浅色外观和青色主题;仅使用本地状态。· 实现参考
02

Mantine 设计系统设计参考

已核实从 @mantine/core 9.6.3 中选取的 DEFAULT_THEME 值。数值像素等效值以 16px 根字号和 theme.scale=1 为前提;缩放后的令牌通过 --mantine-scale 解析。青色主色、色阶 8 和圆角 md 均为明确的应用覆盖值。

示例中使用的青色调色板

来源
名称 / 规则值 / 配置用途
colors.cyan[0]#e3fafc 克制的主题摘要界面表面。
colors.cyan[1]#c5f6fa 浅色调。
colors.cyan[2]#99e9f2 浅色调。
colors.cyan[3]#66d9e8 浅色调。
colors.cyan[4]#3bc9db 中间浅色调。
colors.cyan[5]#22b8cf 中间深色调。
colors.cyan[6]#15aabf 标准调色板色阶。
colors.cyan[7]#1098ad 更深的色调。
colors.cyan[8]#0c8599 选定的主操作色阶。
colors.cyan[9]#0b7285 醒目的文字强调色。

缩放比例为 1 时的字号比例

来源
名称 / 规则值 / 配置用途
fontSizes.xs / sm12px / 14px记录 ID / 辅助文本。
fontSizes.md / lg / xl16px / 18px / 20px默认正文和较大字号。
lineHeights.xs / sm / md1.4 / 1.45 / 1.55成对的正文字号。
lineHeights.lg / xl1.6 / 1.65较大的阅读字号。
headings.h134px / 1.3参与者会话标题。
headings.h2 / h326px / 1.35; 22px / 1.4可用的标题层级。
fontFamilyPlatform sans-serif stack无需下载字体。

缩放比例为 1 时的间距和圆角

来源
名称 / 规则值 / 配置用途
spacing.xs / sm10px / 12px小间距。
spacing.md / lg / xl16px / 20px / 32px移动端内边距 / 字段间距 / 区块间距。
radius.xs / sm2px / 4px小尺寸几何参数。
radius.md / lg / xl8px / 16px / 32px示例默认 / 较大的圆角。
defaultRadiusmd (application override)由 createTheme 集中应用。

断点

来源
名称 / 规则值 / 配置用途
breakpoints.xs36em以默认 16px 为基准时为 576px。
breakpoints.sm48em摘要卡片变为三列。
breakpoints.md62em以默认 16px 为基准时为 992px。
breakpoints.lg / xl75em / 88em以默认 16px 为基准时为 1200px / 1408px。

CSS 与组件映射

来源
名称 / 规则值 / 配置用途
--mantine-primary-color-filledResolved from primaryColor and primaryShade示例选择青色色阶 8。
--mantine-spacing-lgcalc(1.25rem * var(--mantine-scale))Stack 间距为 lg,面板内边距为 lg。
--mantine-radius-mdcalc(0.5rem * var(--mantine-scale))默认圆角面板。
--mantine-font-size-smcalc(0.875rem * var(--mantine-scale))表格记录标签。
Button.extend defaultPropssize: sm明确设置的应用默认值。
TextInput.extend defaultPropssize: md明确设置的应用默认值。
03

Mantine 设计系统完整指南

实用指南,介绍如何为真实界面选择、应用和评审此系统。

DESIGN-mantine.md

完整指导、实现起点和源代码链接。

下载指南

Mantine 设计系统:Mantine 的主题与包边界

一个 Provider,三个功能包

示例使用 core 构建界面,使用 form 进行验证和字段绑定,使用 dates 提供日历输入。MantineProvider 接收 createTheme 覆盖值。core CSS 和 dates CSS 都需要导入;仅加载 React 组件不足以还原经过样式处理的日历。

摘自本 OpenDesign 指南

主题选择青色,primaryShade 设为 8,defaultRadius 设为 md。Button.extend 将小号按钮设为应用默认尺寸,而 TextInput.extend 将中号控件设为默认尺寸。这些是源码中明确展示的设置,并不表示每个 Mantine 产品都应该采用这些设置。

阅读配套规范

Mantine 设计系统:使用调色板索引和解析后的颜色角色

有序调色板并非一组互不相关的色块

Mantine 颜色以索引色阶数组表示。本示例使用 cyan.0 作为克制的摘要面板背景,使用 cyan.9 作为强调文字,并使用配置的主色色阶作为填充操作的颜色。此参考列出了该主题使用的完整青色色阶。

表格中的已确认徽标使用浅青色变体;已撤回状态使用橙色。状态文字仍会显示。撤回操作会更改同意状态,但会保留此前的会话记录,避免因颜色变化而悄然删除历史记录。

阅读配套规范

主题颜色与任意 CSS

组件的 color 属性可以引用命名调色板;若单独使用原始十六进制值设置背景,则会绕过部分变体决策。使用纯 CSS 时,重复应用主题决策应优先使用生成的变量。示例中的 CSS 变量映射说明了哪些值仍与缩放比例和主色保持关联。

阅读配套规范

Mantine 设计系统:应用导出的字体和标题字号比例

还原层级关系

表格中的姓名和研究项目标签使用 sm 字号,标识符和日期使用 xs 字号。Title order={1} 使用 h1 字号比例;抽屉使用语义层级为 h2 的标题,并通过 size="h3" 渲染,使其视觉层级更紧凑。这些设置独立于输入组件提供的标签和辅助文本。

Mantine 的平台字体栈无需下载远程字体。经过缩放的字体值包含 --mantine-scale;参考中的像素值以 scale 为 1 为前提。如果应用更改了 scale,请勿将这些像素等效值视为固定不变。

阅读配套规范

Mantine 设计系统:将 useForm 绑定到实际输入组件

验证应由表单模型负责

initialValues 包含姓名、研究项目、可为空的日期和布尔型同意状态。validate 会为姓名、日期和同意字段返回错误字符串或 null。form.onSubmit 会先执行验证,再将记录添加到本地列表。无需另外维护一组手动绘制的错误标签。

TextInput 和 DatePickerInput 通过 getInputProps 绑定到对应字段路径。Checkbox 还需指定 type:"checkbox",以正确绑定选中值。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 包含 provider 和主题,因此无需额外的隐藏 provider 文件。

不要未经检查就照搬其他主版本中的日期示例,先确认其值类型。表单的初始日期和验证逻辑必须与实际的 DatePickerInput API 保持一致。此示例基于指定的包版本构建,而非根据旧教程推断。

  1. 安装 core、hooks、form、dates,以及 dates 所依赖的 dayjs。
  2. 在应用入口处各引入一次 core/styles.css 和 dates/styles.css。
  3. 运行表单,添加一条带日期的记录,然后检查表格和撤回结果。

Mantine 设计系统:将日历、表单和表格作为一个整体进行验证

试用内容

提交空抽屉,查看姓名、日期和同意相关错误。填写姓名,在日历中选择日期,并确认示例同意,然后再次提交。新参与者应显示所选日期和稳定的预览 ID。接着撤回该参与者的同意,并查看行内容和摘要的变化。

该数据模型刻意保持精简,仅驻留内存。它不包含研究招募、同意收集、服务器持久化或时区转换。此示例的实际价值在于原生包集成和直观呈现的控件行为,而非暗示其具备研究管理后端。

Mantine 设计系统组件示例

App.jsx — provider、主题、表格和排期抽屉

完整的原生 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>}

代码参考

  • 已同时引入 core 和 dates CSS。
  • 同意复选框是示例中的验证条件,并非真实的同意收集流程。
04

Mantine 设计系统 AI Agent 设置

实现起点

使用所选 Vite 模板支持的 Node 版本。源代码包含 provider、主题和样式表导入;演示流程无需后端或自定义 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

适用于你项目的提示词

Agent 提示词
使用提供的 Mantine 9.6.3 组合,并保持 core/form/dates 版本一致。保留 provider、两个 CSS 导入、getInputProps 绑定、日期值类型和表格滚动边界。只有在明确同意和持久化策略后,才将本地登记变更替换为真实服务。撤回应与删除区分开,并确保输入错误清晰可读、抽屉焦点管理正常。
05

Mantine 设计系统来源与范围

基于 Mantine 9.6.3 的原始 OpenDesign 示例。此处区分默认主题值与青色/形状应用覆盖项。原生预览仅演示本地记录和验证,不会收集同意或保存研究数据。