Mantine Vanilla Extract 集成指南:用 themeToVars 将 Mantine 主题转换为类型安全的 CSS 变量

Mantine Vanilla Extract 集成指南:用 themeToVars 将 Mantine 主题转换为类型安全的 CSS 变量 Mantine Vanilla Extract 集成指南用 themeToVars 将 Mantine 主题转换为类型安全的 CSS 变量【免费下载链接】mantineA fully featured React components library项目地址: https://gitcode.com/GitHub_Trending/ma/mantinemantine/vanilla-extract是 Mantine 官方提供的 vanilla-extract 主题集成包它的核心使命只有一条把 Mantine 主题对象MantineTheme转换成可供*.css.ts文件直接消费的 CSS 变量对象。本文基于该包在仓库内的 README、官方文档页 vanilla-extract.mdx 以及themeToVars的源码实现完整讲解安装方式、工作原理、vars 对象结构以及主题转换、响应式媒体查询、亮暗色与 RTL 选择器的实战用法。读完本文你将能够在 vanilla-extract 项目中直接以类型安全的方式访问 Mantine 的字体、间距、颜色、阴影与断点令牌。包定位Mantine 主题与 vanilla-extract 之间的桥接按 README 的描述这个包的功能是Mantine theme integration with vanilla-extractMantine 主题与 vanilla-extract 的集成。它的公开 API 非常收敛从 入口文件 可以看到全部导出只有两项themeToVars—— 把 Mantine 主题对象转换为 CSS 变量对象的核心函数MantineVars—— 转换结果的 TypeScript 类型。vanilla-extract 本身是一个基于 TypeScript 的 CSS 预处理器它会在构建时把*.css.ts文件编译为静态 CSS因此运行时没有任何样式计算开销。Mantine 的官方文档将其定位为 CSS Modules 在用 TypeScript 写样式这个方向上的替代方案两者可以在同一项目中共存而互不影响性能与包体积。安装与前置条件mantine/vanilla-extract的安装非常简单README 给出了 yarn 与 npm 两种方式# With yarn yarn add mantine/vanilla-extract # With npm npm install mantine/vanilla-extract从 package.json 可以看到它的依赖关系与分发形态peerDependenciesmantine/core9.6.0即它依赖同版本的mantine/core提供createTheme、mergeMantineTheme、DEFAULT_THEME、rem/em等基础能力sideEffects: false可以安全参与 tree-shaking同时提供esm、cjs与类型声明兼容import与require两种消费方式。需要特别说明的是这个包不包含 vanilla-extract 本体。你需要先按照 vanilla-extract 官方指引在你的构建工具中安装 vanilla-extract 及其构建插件如 Next.js、Vite 的插件再安装本包。仓库文档中提到官方提供了vite-vanilla-extract-template与next-vanilla-extract-template两个仅含最小配置的模板可作为起步参考。对比vanilla-extract 与 CSS Modules在决定引入 vanilla-extract 之前值得先理解它与 CSS Modules 的异同详见 vanilla-extract.mdx两者的共同点样式都在构建时生成没有运行时开销类名被限定在样式文件作用域内不会全局污染。两者的差异vanilla-extract 的样式是类型安全的写错的属性名或值会在编译期报错在 vanilla-extract 中可以使用任意 JavaScript/TypeScript 代码来生成样式包括 颜色函数但 vanilla-extract无法使用postcss-preset-mantine 提供的light-dark函数与hovermixin 等特性——因此不能把 Mantine 文档中所有 demo 原样复制到 vanilla-extract 项目里vanilla-extract 需要额外的构建配置主流工具Next.js、Vite都有官方插件但小众构建工具可能需要自行配置。主题转换themeToVars 的工作原理Mantine 的主题机制与 vanilla-extract 有一个关键交集Mantine 的每个主题属性本身就已经以 CSS 变量--mantine-*的形式暴露在页面上见 CSS 变量文档。因此官方明确建议不要用 vanilla-extract 的createTheme去重新生成 Mantine 主题令牌而应该用themeToVars直接创建一份指向这些既有 CSS 变量的对象。用法示例先定义一个 Mantine 主题记得传给MantineProvider// theme.ts import { createTheme } from mantine/core; // Do not forget to pass theme to MantineProvider export const theme createTheme({ fontFamily: serif, primaryColor: cyan, });再在theme.css.ts中将其转换为 CSS 变量对象// theme.css.ts import { theme } from ./theme; import { themeToVars } from mantine/vanilla-extract; // CSS variables object, can be access in *.css.ts files export const vars themeToVars(theme);之后在任意*.css.ts文件中导入vars即可类型安全地访问 Mantine 令牌。源码机制从 theme-to-vars.ts 的实现可以看到转换过程分三步合并主题themeToVars首先调用mergeMantineTheme(DEFAULT_THEME, theme)把传入的主题覆盖项与 Mantine 默认主题合并。这意味着即使你的createTheme只覆盖了primaryColor返回的vars对象也始终包含完整的默认令牌集合。生成尺寸令牌核心辅助函数getSizesVariables遍历fontSizes、lineHeights、shadows、radius、spacing等键值对象为每个尺寸生成形如var(--mantine-font-size-xl)、var(--mantine-spacing-md)的变量引用。生成颜色与语义令牌对每个颜色名称生成 0–9 十个色阶以及filled、light、outline及各自的hover/color变体另外内置了primary、white、black、text、body、error、placeholder、anchor、default、dimmed、disabled*等语义令牌。默认主题的断点定义位于 default-theme.tsxs: 36em、sm: 48em、md: 62em、lg: 75em、xl: 88em它们会被直接暴露在vars.breakpoints中供largerThan/smallerThan使用。vars 对象结构MantineVars 类型全景themeToVars的返回值类型为MantineVars完整定义见 types.ts主要分为四组全局基础令牌scale、cursorType、webkitFontSmoothing、mozFontSmoothinglineHeight、fontFamily、fontFamilyMonospace、fontFamilyHeadings、headingFontWeight、radiusDefaultbreakpoints直接引用合并后主题的断点值而非 CSS 变量。尺寸令牌spacing、fontSizes、lineHeights、shadows、radius每个都是{ xs: var(--mantine-*-xs), sm: ..., ... }形式类型上使用MantineSpacing | (string {})联合类型因此自定义尺寸名也能通过类型检查。颜色令牌colors为每个颜色提供0–9色阶与filled、filledHover、light、lightHover、lightColor、outline、outlineHover另有primary、primaryColors、white、black、text、body、error、placeholder、anchor、default、defaultHover、defaultColor、defaultBorder、dimmed、disabledBody、disabledText、disabledBorder等语义令牌。标题令牌headings为h1–h6各提供fontSize、lineHeight、fontWeight三个变量引用对应--mantine-h1-font-size等 CSS 变量。选择器与媒体查询辅助这是面向 vanilla-extract 的专属能力见下一节。亮暗色与 RTL 选择器vars内置了三个选择器字符串可直接用于 vanilla-extract 的selectors语法它们实际指向 Mantine 在html元素上设置的data-mantine-color-scheme与dir属性vars.lightSelector→[data-mantine-color-schemelight] vars.darkSelector→[data-mantine-color-schemedark] vars.rtlSelector→[dirrtl] 亮暗色用法示例// Demo.css.ts import { style } from vanilla-extract/css; import { vars } from ./theme; export const demo style({ fontSize: vars.fontSizes.xl, selectors: { [vars.lightSelector]: { backgroundColor: vars.colors.red[5], color: vars.colors.white, }, [vars.darkSelector]: { backgroundColor: vars.colors.blue[5], color: vars.colors.white, }, }, });官方建议通常只用一个先书写亮色主题的默认样式再用vars.darkSelector覆盖暗色样式或反过来代码更简洁// Demo.css.ts import { style } from vanilla-extract/css; import { vars } from ./theme; export const demo style({ fontSize: vars.fontSizes.xl, backgroundColor: vars.colors.red[5], color: vars.colors.white, selectors: { [vars.darkSelector]: { backgroundColor: vars.colors.blue[5], color: vars.colors.white, }, }, });RTL 场景同理例如用vars.rtlSelector在从右到左排版时把paddingRight翻转为paddingLeft// Demo.css.ts import { style } from vanilla-extract/css; import { vars } from ./theme; export const demo style({ paddingRight: vars.spacing.md, selectors: { [vars.rtlSelector]: { paddingLeft: vars.spacing.md, paddingRight: 0, }, }, });响应式largerThan 与 smallerThanvars提供两个媒体查询辅助函数是min-width/max-width的简写实现见 theme-to-vars.ts 中的getBreakpointValue传入数字如640时会被em()函数转换为 em 单位640px→40em与 Mantine 断点保持一致的相对单位体系传入断点名称如sm时会直接使用合并后主题中该断点的值默认48em传入的数字若恰好等于某个断点名称的键如sm优先取断点值否则走em()转换。// Demo.css.ts import { style } from vanilla-extract/css; import { vars } from ./theme; export const demo style({ fontSize: vars.fontSizes.sm, media: { // equivalent to (min-width: 640px) converted to em // - (min-width: 40em) [vars.largerThan(640)]: { fontSize: vars.fontSizes.md, }, // equivalent to (max-width: 640px) converted to em // - (max-width: 40em) [vars.smallerThan(640)]: { fontSize: vars.fontSizes.xs, }, // You can reference theme.breakpoints values [vars.largerThan(sm)]: { fontSize: vars.fontSizes.md, }, }, });px 与 rem/em 转换在样式文件中需要把 px 转换为 rem 或 em 时直接使用mantine/core导出的rem与em函数即可无需引入额外依赖// Demo.css.ts import { style } from vanilla-extract/css; import { rem } from mantine/core; export const demo style({ fontSize: rem(16), media: { [(min-width: ${em(768)})]: { fontSize: rem(18), }, }, });样式编写入门示例最后把前面的知识点串起来一个完整的 vanilla-extract 样式文件长这样// Demo.css.ts import { style } from vanilla-extract/css; import { vars } from ./theme; export const demo style({ fontSize: vars.fontSizes.xl, backgroundColor: vars.colors.red[5], color: vars.colors.white, });这里vars.fontSizes.xl、vars.colors.red[5]、vars.colors.white都有完整的类型提示任何拼写错误都会在编译期被拦截这正是 vanilla-extract 相比普通 CSS Modules 的核心体验优势。注意事项与限制主题必须传给MantineProviderthemeToVars生成的是对--mantine-*变量的引用只有MantineProvider在运行时真正注入这些变量后样式才能生效。无法直接复制 Mantine 文档 demo由于缺少 postcss-preset-mantine 的light-dark、hovermixin 等特性部分文档示例需要改写后才能用于 vanilla-extract。构建工具要求需要为 Next.js、Vite 等配置 vanilla-extract 插件小众构建工具可能需自行接入。与 CSS Modules 可共存同一项目中同时使用两种方案不会影响性能或包体积。该包以 MIT 协议开源见 README核心源码仅两个文件theme-to-vars.ts 与 types.ts实现简洁、依赖收敛非常适合在类型安全优先的 vanilla-extract 工程中直接引入。【免费下载链接】mantineA fully featured React components library项目地址: https://gitcode.com/GitHub_Trending/ma/mantine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考