前端开发
在 Mantine 中创建可主题化自定义组件并接入…
当使用 @mantine/core 并需要新建或扩展组件、接入 Mantine 主题与 Styles API、实现 CSS 变量、复合组件或多态/泛型组件时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 Mantine 中创建可主题化自定义特定
解决思路
- 按组件模板落地:从 '@mantine/core' 导入 Box、BoxProps、createVarsResolver、ElementProps、factory、Factory、getRadius、MantineRadius、StylesApiProps、useProps、useStyles;从 './MyComponent.module.css' 导入 classes。
- 定义导出类型:`MyComponentStylesNames = 'root' | 'inner'`;`MyComponentVariant = 'filled' | 'outline'`;`MyComponentCssVariables = { root: '--my-radius' }`。
- 定义 props interface:`MyComponentProps` 继承 `BoxProps, StylesApiProps<MyComponentFactory>, ElementProps<'div'>`,并增加业务 props,例如 `radius?: MantineRadius`。
- 定义 factory 类型:`MyComponentFactory = Factory<{ props: MyComponentProps; ref: HTMLDivElement; stylesNames: MyComponentStylesNames; vars: MyComponentCssVariables; variant: MyComponentVariant; }>`。
- 设置默认 props:`const defaultProps = { radius: 'md' } satisfies Partial<MyComponentProps>;`。
- 创建 CSS 变量解析器:`const varsResolver = createVarsResolver<MyComponentFactory>((_theme, { radius }) => ({ root: { '--my-radius': getRadius(radius) } }));`。
- 创建组件:`export const MyComponent = factory<MyComponentFactory>((_props) => { ... });`。
- 在 factory 内调用 `const props = useProps('MyComponent', defaultProps, _props);` 合并默认 props。
- 解构 props:`const { classNames, className, style, styles, unstyled, vars, attributes, radius, ...others } = props;`。
- 调用 `useStyles<MyComponentFactory>({ name: 'MyComponent', classes, props, className, style, classNames, styles, unstyled, vars, attributes, varsResolver });` 获取 `getStyles`。
- 返回根元素:`return <Box {...getStyles('root')} {...others} />;`;按需对子元素使用 `getStyles('inner')` 等。
- 设置静态属性:`MyComponent.displayName = '@mantine/core/MyComponent';` 和 `MyComponent.classes = classes;`。
- 选择 factory 变体:标准组件用 `factory()`,类型 `Factory<{}>`。
- 支持 `component` prop(多态)用 `polymorphicFactory()`,类型 `PolymorphicFactory<{}>`,并添加 `defaultComponent` 和 `defaultRef`。
- Props 随泛型变化(例如 `multiple`)用 `genericFactory()`,类型 `Factory<{ signature: ... }>`。
- 谨慎使用 `polymorphicFactory`:它会增加 TypeScript 开销并拖慢 IDE 自动补全。
- 配置 Factory 类型字段 `props`:必填,指定组件 props 类型。
- 配置 `ref`:指定 forwarded ref 的元素类型,例如 `HTMLDivElement`。
- 配置 `stylesNames`:Styles API 选择器联合,例如 `'root' | 'inner'`。
- 配置 `vars`:每个选择器的 CSS 变量映射,例如 `{ root: '--my-var' }`。
- 配置 `variant`:接受的 variant 字符串,例如 `'filled' | 'outline'`。
- 配置 `staticComponents`:声明子组件以支持复合模式,例如 `{ Item: typeof MyComponentItem }`。
- 配置 `compound?: boolean`:设为 true 表示子组件;会禁用主题 classNames/styles/vars。
- 配置 `ctx?: MyContextType`:作为第三参数传给 styles/vars 解析器。
- 配置 `signature?: (...) => JSX.Element`:仅用于 `genericFactory`。
- 通过主题注册:在 `createTheme({ components: { MyComponent: MyComponent.extend({ ... }) } })` 中覆盖默认值。
- 在 `MyComponent.extend()` 中可设置 `defaultProps`,例如 `{ radius: 'xl' }`。
- 在 `MyComponent.extend()` 中可设置 `classNames`,例如 `{ root: 'my-root' }`。
- 在 `MyComponent.extend()` 中可设置 `styles`,例如 `{ root: { color: 'red' } }`。
- 在 `MyComponent.extend()` 中可设置 `vars` 解析器,例如 `(_theme, props) => ({ root: { '--my-radius': getRadius(props.radius) } })`。
- 查阅 `references/api.md` 获取所有导入:`factory`、`useProps`、`useStyles`、`createVarsResolver`、`createSafeContext`、`StylesApiProps`、`CompoundStylesApiProps`、`BoxProps`、`ElementProps` 以及主题辅助函数(`getSize`、`getRadius` 等)。
- 查阅 `references/patterns.md` 获取完整示例:带 context 的复合组件、多态组件、泛型组件、主题集成。
适用边界 · 注意事项
- 不适用于不使用 Mantine 或 @mantine/core 的项目。
- 如果只是简单一次性样式组件,不需要 Styles API、CSS 变量、主题覆盖或复合组件,用普通 React 组件即可,避免 factory/useStyles 开销。
- 不要滥用 polymorphicFactory,因为它增加 TypeScript 开销并拖慢 IDE 自动补全。