mantine-custom-components

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mantine Custom Components Skill

Mantine 自定义组件技能

Component template

组件模板

tsx
import {
  Box, BoxProps, createVarsResolver, ElementProps,
  factory, Factory, getRadius, MantineRadius,
  StylesApiProps, useProps, useStyles,
} from '@mantine/core';
import classes from './MyComponent.module.css';

export type MyComponentStylesNames = 'root' | 'inner';
export type MyComponentVariant = 'filled' | 'outline';
export type MyComponentCssVariables = { root: '--my-radius' };

export interface MyComponentProps
  extends BoxProps, StylesApiProps<MyComponentFactory>, ElementProps<'div'> {
  radius?: MantineRadius;
}

export type MyComponentFactory = Factory<{
  props: MyComponentProps;
  ref: HTMLDivElement;
  stylesNames: MyComponentStylesNames;
  vars: MyComponentCssVariables;
  variant: MyComponentVariant;
}>;

const defaultProps = { radius: 'md' } satisfies Partial<MyComponentProps>;

const varsResolver = createVarsResolver<MyComponentFactory>((_theme, { radius }) => ({
  root: { '--my-radius': getRadius(radius) },
}));

export const MyComponent = factory<MyComponentFactory>((_props) => {
  const props = useProps('MyComponent', defaultProps, _props);
  const { classNames, className, style, styles, unstyled, vars, attributes, radius, ...others } = props;

  const getStyles = useStyles<MyComponentFactory>({
    name: 'MyComponent', classes, props,
    className, style, classNames, styles, unstyled, vars, attributes, varsResolver,
  });

  return <Box {...getStyles('root')} {...others} />;
});

MyComponent.displayName = '@mantine/core/MyComponent';
MyComponent.classes = classes;
tsx
import {
  Box, BoxProps, createVarsResolver, ElementProps,
  factory, Factory, getRadius, MantineRadius,
  StylesApiProps, useProps, useStyles,
} from '@mantine/core';
import classes from './MyComponent.module.css';

export type MyComponentStylesNames = 'root' | 'inner';
export type MyComponentVariant = 'filled' | 'outline';
export type MyComponentCssVariables = { root: '--my-radius' };

export interface MyComponentProps
  extends BoxProps, StylesApiProps<MyComponentFactory>, ElementProps<'div'> {
  radius?: MantineRadius;
}

export type MyComponentFactory = Factory<{
  props: MyComponentProps;
  ref: HTMLDivElement;
  stylesNames: MyComponentStylesNames;
  vars: MyComponentCssVariables;
  variant: MyComponentVariant;
}>;

const defaultProps = { radius: 'md' } satisfies Partial<MyComponentProps>;

const varsResolver = createVarsResolver<MyComponentFactory>((_theme, { radius }) => ({
  root: { '--my-radius': getRadius(radius) },
}));

export const MyComponent = factory<MyComponentFactory>((_props) => {
  const props = useProps('MyComponent', defaultProps, _props);
  const { classNames, className, style, styles, unstyled, vars, attributes, radius, ...others } = props;

  const getStyles = useStyles<MyComponentFactory>({
    name: 'MyComponent', classes, props,
    className, style, classNames, styles, unstyled, vars, attributes, varsResolver,
  });

  return <Box {...getStyles('root')} {...others} />;
});

MyComponent.displayName = '@mantine/core/MyComponent';
MyComponent.classes = classes;

Factory variant — which to use

Factory 变体选择指南

ScenarioFactory functionType
Standard component
factory()
Factory<{}>
Supports
component
prop (polymorphic)
polymorphicFactory()
PolymorphicFactory<{}>
— add
defaultComponent
and
defaultRef
Props change based on a generic (e.g.
multiple
)
genericFactory()
Factory<{ signature: ... }>
Use
polymorphicFactory
sparingly — it adds TypeScript overhead and slows IDE autocomplete.
场景Factory 函数类型
标准组件
factory()
Factory<{}>
支持
component
属性(多态)
polymorphicFactory()
PolymorphicFactory<{}>
— 添加
defaultComponent
defaultRef
属性随泛型变化(如
multiple
genericFactory()
Factory<{ signature: ... }>
谨慎使用
polymorphicFactory
——它会增加TypeScript的开销并降低IDE自动补全速度。

Factory type fields

Factory 类型字段

ts
Factory<{
  props: MyComponentProps;       // required
  ref: HTMLDivElement;           // element type for the forwarded ref
  stylesNames: 'root' | 'inner'; // union of Styles API selectors
  vars: { root: '--my-var' };    // CSS variable map per selector
  variant: 'filled' | 'outline'; // accepted variant strings
  staticComponents: {            // sub-components (compound pattern)
    Item: typeof MyComponentItem;
  };
  compound?: boolean;            // true = sub-component; disables theme classNames/styles/vars
  ctx?: MyContextType;           // passed to styles/vars resolvers as third arg
  signature?: (...) => JSX.Element; // only for genericFactory
}>
ts
Factory<{
  props: MyComponentProps;       // 必填
  ref: HTMLDivElement;           // 转发ref的元素类型
  stylesNames: 'root' | 'inner'; // Styles API 选择器的联合类型
  vars: { root: '--my-var' };    // 每个选择器对应的CSS变量映射
  variant: 'filled' | 'outline'; // 支持的变体字符串
  staticComponents: {            // 子组件(复合组件模式)
    Item: typeof MyComponentItem;
  };
  compound?: boolean;            // 为true时表示是子组件;禁用主题classNames/styles/vars
  ctx?: MyContextType;           // 作为第三个参数传递给样式/变量解析器
  signature?: (...) => JSX.Element; // 仅适用于genericFactory
}>

Theme integration

主题集成

Users and the theme can override defaults via
Component.extend()
:
ts
const theme = createTheme({
  components: {
    MyComponent: MyComponent.extend({
      defaultProps: { radius: 'xl' },
      classNames: { root: 'my-root' },
      styles: { root: { color: 'red' } },
      vars: (_theme, props) => ({ root: { '--my-radius': getRadius(props.radius) } }),
    }),
  },
});
用户和主题可通过
Component.extend()
覆盖默认配置:
ts
const theme = createTheme({
  components: {
    MyComponent: MyComponent.extend({
      defaultProps: { radius: 'xl' },
      classNames: { root: 'my-root' },
      styles: { root: { color: 'red' } },
      vars: (_theme, props) => ({ root: { '--my-radius': getRadius(props.radius) } }),
    }),
  },
});

References

参考资料

  • references/api.md
    — All imports:
    factory
    ,
    useProps
    ,
    useStyles
    ,
    createVarsResolver
    ,
    createSafeContext
    ,
    StylesApiProps
    ,
    CompoundStylesApiProps
    ,
    BoxProps
    ,
    ElementProps
    , theme helpers (
    getSize
    ,
    getRadius
    , etc.)
  • references/patterns.md
    — Full examples: compound components with context, polymorphic component, generic component, theme integration
  • references/api.md
    — 所有导入项:
    factory
    useProps
    useStyles
    createVarsResolver
    createSafeContext
    StylesApiProps
    CompoundStylesApiProps
    BoxProps
    ElementProps
    、主题工具函数(
    getSize
    getRadius
    等)
  • references/patterns.md
    — 完整示例:带上下文的复合组件、多态组件、泛型组件、主题集成