Variants와 sizes
Variants와 sizes
커스텀 variants 추가
대부분의 Mantine 컴포넌트는 variant prop을 지원해요. 이 prop은 CSS variables resolver에서 사용할 수 있고, 컴포넌트의 루트 요소에 data-variant="{value}" 속성으로도 노출돼요. 커스텀 variants를 추가하는 가장 쉬운 방법은 [data-variant="{value}"]를 사용하는 스타일을 추가하는 거예요.
Input 컴포넌트에 새 variant를 추가하는 예시:
-
underlinevariant 스타일이 추가돼요 -
filledvariant는 기본 variant이며 추가 스타일을 정의할 필요가 없어요
import { Input, MantineProvider, createTheme } from '@mantine/core';
import classes from './Demo.module.css';
// It is better to add new variants in theme.components
// This way you will be able to use them in anywhere in the app
const theme = createTheme({
components: {
Input: Input.extend({ classNames: classes }),
}
});
function Demo() {
return (
<MantineProvider theme={theme}>
<Input variant="underline" placeholder="Underline input" />
</MantineProvider>
);
}
Styles API를 지원하는 모든 Mantine 컴포넌트에 커스텀 variants를 추가할 수 있다는 점에 주의하세요. 라이브러리 쪽에 variants가 정의되어 있지 않아도 돼요.
기존 variants 스타일 재정의
새 variants를 추가하는 것 외에 기존 것도 재정의할 수 있어요. 예를 들어 .input[data-variant="filled"] selector로 Input 컴포넌트의 filled variant를 바꿀 수 있어요.
출처: 문서
본문
커스텀 variants 타입
프로젝트에 mantine.d.ts 파일을 만들고 {x}Props 인터페이스를 새 variant 타입으로 확장해 커스텀 variants의 타입을 정의할 수 있어요.
Button 컴포넌트에 커스텀 variant 타입을 추가하는 예시:
import { ButtonVariant, MantineSize } from '@mantine/core';
type ExtendedButtonVariant = ButtonVariant | 'contrast' | 'radial-gradient';
declare module '@mantine/core' {
export interface ButtonProps {
variant?: ExtendedButtonVariant;
}
}
variantColorResolver
Button, Badge, ActionIcon 및 다른 컴포넌트는 variantColorResolver로 커스텀 variants를 지원해요 – 색상 변경과 새 variants 추가를 모두 지원해요. theme.variantColorResolver는 색상만 담당한다는 점에 주의하세요. 다른 속성을 바꿔야 한다면 data-variant 속성을 사용해요.
import {
Button,
Group,
MantineProvider,
defaultVariantColorsResolver,
VariantColorsResolver,
parseThemeColor,
rgba,
darken,
} from '@mantine/core';
const variantColorResolver: VariantColorsResolver = (input) => {
const defaultResolvedColors = defaultVariantColorsResolver(input);
const parsedColor = parseThemeColor({
color: input.color || input.theme.primaryColor,
theme: input.theme,
});
// Override some properties for variant
if (parsedColor.isThemeColor && parsedColor.color === 'lime' && input.variant === 'filled') {
return {
...defaultResolvedColors,
color: 'var(--mantine-color-black)',
hoverColor: 'var(--mantine-color-black)',
};
}
// Completely override variant
if (input.variant === 'light') {
return {
background: rgba(parsedColor.value, 0.1),
hover: rgba(parsedColor.value, 0.15),
border: `1px solid ${parsedColor.value}`,
color: darken(parsedColor.value, 0.1),
};
}
// Add new variants support
if (input.variant === 'danger') {
return {
background: 'var(--mantine-color-red-9)',
hover: 'var(--mantine-color-red-8)',
color: 'var(--mantine-color-white)',
border: 'none',
};
}
return defaultResolvedColors;
};
function Demo() {
return (
<MantineProvider theme={{ variantColorResolver }}>
<Group>
<Button color="lime" variant="filled">Lime filled button</Button>
<Button color="orange" variant="light">Orange light button</Button>
<Button variant="danger">Danger button</Button>
</Group>
</MantineProvider>
);
}
컴포넌트 CSS variables로 sizes 추가
size prop을 지원하는 어떤 컴포넌트든 커스텀 CSS variables resolver를 제공해 커스텀 sizes를 추가할 수 있어요. 보통 이것은 theme.components에서 해요:
import { Button, Group, MantineProvider, createTheme } from '@mantine/core';
const theme = createTheme({
components: {
Button: Button.extend({
vars: (theme, props) => {
if (props.size === 'xxl') {
return {
root: {
'--button-height': '60px',
'--button-padding-x': '30px',
'--button-fz': '24px',
},
};
}
if (props.size === 'xxs') {
return {
root: {
'--button-height': '24px',
'--button-padding-x': '10px',
'--button-fz': '10px',
},
};
}
return { root: {} };
},
}),
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
<Group>
<Button size="xxl">XXL Button</Button>
<Button size="xxs">XXS Button</Button>
</Group>
</MantineProvider>
);
}
data-size 속성으로 sizes 추가
size prop을 지원하는 모든 컴포넌트는 그것을 루트 요소의 data-size="{value}" 속성으로 노출해요. 이것으로 커스텀 sizes를 추가할 수 있어요:
import { Input, createTheme, MantineProvider } from '@mantine/core';
import classes from './Demo.module.css';
const theme = createTheme({
components: {
Input: Input.extend({ classNames: classes }),
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
<Input size="xxl" placeholder="XXL input" />
</MantineProvider>
);
}
.input[data-size='xxl'] {
--input-height: 60px;
}
정적 CSS variables로 sizes 추가
Mantine 컴포넌트 sizes는 CSS variables로 정의돼요(보통 루트 요소에). 예를 들어 ActionIcon 컴포넌트는 다음 CSS variables를 가져요:
.root {
--ai-size-xs: 18px;
--ai-size-sm: 22px;
--ai-size-md: 28px;
--ai-size-lg: 34px;
--ai-size-xl: 44px;
}
이 값들을 Styles API로 재정의하거나 새 size 값을 추가할 수 있어요:
import { ActionIcon, createTheme, Group, MantineThemeProvider } from '@mantine/core';
import { HeartIcon } from '@phosphor-icons/react';
import classes from './Demo.module.css';
const theme = createTheme({
components: {
ActionIcon: ActionIcon.extend({
classNames: classes,
}),
},
});
function Demo() {
return (
<MantineThemeProvider theme={theme}>
<Group>
<ActionIcon size="xl"><HeartIcon /></ActionIcon>
<ActionIcon size="xxl"><HeartIcon /></ActionIcon>
</Group>
</MantineThemeProvider>
);
}
일부 컴포넌트는 size에 대해 하나 이상의 CSS variable을 가진다는 점에 주의하세요. 예를 들어 Button 컴포넌트는 다음 CSS variables를 가져요:
.root {
--button-height-xs: 30px;
--button-height-sm: 36px;
--button-height-md: 42px;
--button-height-lg: 50px;
--button-height-xl: 60px;
--button-height-compact-xs: 22px;
--button-height-compact-sm: 26px;
--button-height-compact-md: 30px;
--button-height-compact-lg: 34px;
--button-height-compact-xl: 40px;
--button-padding-x-xs: 14px;
--button-padding-x-sm: 18px;
--button-padding-x-md: 22px;
--button-padding-x-lg: 26px;
--button-padding-x-xl: 32px;
--button-padding-x-compact-xs: 7px;
--button-padding-x-compact-sm: 8px;
--button-padding-x-compact-md: 10px;
--button-padding-x-compact-lg: 12px;
--button-padding-x-compact-xl: 14px;
}
보통 이런 경우에는 theme의 data-size 속성이나 vars를 사용해 sizes를 커스터마이즈하는 것이 더 편리해요.