Theme 객체
Theme 객체
Mantine theme은 애플리케이션의 색상, 폰트, spacing, border-radius 및 기타 디자인 토큰이 저장되는 객체예요.
interface MantineTheme {
/** Controls focus ring styles. Supports the following options:
* - `auto` – focus ring is displayed only when the user navigates with keyboard (default value)
* - `always` – focus ring is displayed when the user navigates with keyboard and mouse
* - `never` – focus ring is always hidden (not recommended)
*/
focusRing: 'auto' | 'always' | 'never';
/** rem units scale; change if you customize font-size of <html> element
* default value is `1` (for `100%`/`16px` font-size on <html>)
*/
scale: number;
/** Determines whether `font-smoothing` property should be set on the body; `true` by default */
fontSmoothing: boolean;
/** White color */
white: string;
/** Black color */
black: string;
/** Object of colors; key is color name, value is an array of at least 10 strings (colors) */
colors: MantineThemeColors;
/** Index of theme.colors[color].
* Primary shade is used in all components to determine which color from theme.colors[color] should be used.
* Can be either a number (0–9) or an object to specify different color shades for light and dark color schemes.
* Default value `{ light: 6, dark: 8 }`
*
* For example,
* { primaryShade: 6 } // shade 6 is used both for dark and light color schemes
* { primaryShade: { light: 6, dark: 7 } } // different shades for dark and light color schemes
* */
primaryShade: MantineColorShade | MantinePrimaryShade;
/** Key of `theme.colors`; hex/rgb/hsl values are not supported.
* Determines which color will be used in all components by default.
* Default value – `blue`.
* */
primaryColor: string;
/** Function to resolve colors based on variant.
* Can be used to deeply customize how colors are applied to `Button`, `ActionIcon`, `ThemeIcon`
* and other components that use colors from the theme.
* */
variantColorResolver: VariantColorsResolver;
/** Determines whether text color must be changed based on the given `color` prop in filled variant
* For example, if you pass `color="blue.1"` to the Button component, text color will be changed to `var(--mantine-color-black)`
* Default value – `false`
* */
autoContrast: boolean;
/** Determines which luminance value is used to determine if text color should be light or dark.
* Used only if `theme.autoContrast` is set to `true`.
* Default value is `0.3`
* */
luminanceThreshold: number;
/** font-family used in all components; system fonts by default */
fontFamily: string;
/** Monospace font-family; used in code and other similar components, system fonts by default */
fontFamilyMonospace: string;
/** Controls various styles of h1-h6 elements; used in Typography and Title components */
headings: {
fontFamily: string;
fontWeight: string;
textWrap: 'wrap' | 'nowrap' | 'balance' | 'pretty' | 'stable';
sizes: {
h1: HeadingStyle;
h2: HeadingStyle;
h3: HeadingStyle;
h4: HeadingStyle;
h5: HeadingStyle;
h6: HeadingStyle;
};
};
/** Object of values that are used to set `border-radius` in all components that support it */
radius: MantineRadiusValues;
/** Key of `theme.radius` or any valid CSS value. Default `border-radius` used by most components */
defaultRadius: MantineRadius;
/** Object of values that are used to set various CSS properties that control spacing between elements */
spacing: MantineSpacingValues;
/** Object of values that are used to control `font-size` property in all components */
fontSizes: MantineFontSizesValues;
/** Object of values that are used to control `line-height` property in `Text` component */
lineHeights: MantineLineHeightValues;
/** Object of values that are used to control `font-weight` property in components */
fontWeights: MantineFontWeightsValues;
/** Object of values that are used to control breakpoints in all components;
* values are expected to be defined in em
* */
breakpoints: MantineBreakpointsValues;
/** Object of values that are used to add `box-shadow` styles to components that support `shadow` prop */
shadows: MantineShadowsValues;
/** Determines whether user OS settings to reduce motion should be respected; `false` by default */
respectReducedMotion: boolean;
/** Determines which cursor type will be used for interactive elements
* - `default` – cursor that is used by native HTML elements, for example, `input[type="checkbox"]` has `cursor: default` styles
* - `pointer` – sets `cursor: pointer` on interactive elements that do not have these styles by default
*/
cursorType: 'default' | 'pointer';
/** Default gradient configuration for components that support `variant="gradient"` */
defaultGradient: MantineGradient;
/** Class added to the elements that have active styles, for example, `Button` and `ActionIcon` */
activeClassName: string;
/** Class added to the elements that have focus styles, for example, `Button` or `ActionIcon`.
* Overrides `theme.focusRing` property.
*/
focusClassName: string;
/** Allows adding `classNames`, `styles` and `defaultProps` to any component */
components: MantineThemeComponents;
/** Any other properties that you want to access with the theme objects */
other: MantineThemeOther;
}
출처: 문서
본문
사용법
theme을 커스터마이즈하려면 MantineProvider theme prop에 theme override 객체를 전달해요. theme override는 기본 theme과 깊게 병합돼요.
import { createTheme, MantineProvider } from '@mantine/core';
const theme = createTheme({
colors: {
// Add your color
deepBlue: [
'#eef3ff',
'#dce4f5',
'#b9c7e2',
'#94a8d0',
'#748dc1',
'#5f7cb8',
'#5474b4',
'#44639f',
'#39588f',
'#2d4b81',
],
// or replace default theme color
blue: [
'#eef3ff',
'#dee2f2',
'#bdc2de',
'#98a0ca',
'#7a84ba',
'#6672b0',
'#5c68ac',
'#4c5897',
'#424e88',
'#364379',
],
},
shadows: {
md: '1px 1px 3px rgba(0, 0, 0, .25)',
xl: '5px 5px 3px rgba(0, 0, 0, .25)',
},
headings: {
fontFamily: 'Roboto, sans-serif',
sizes: {
h1: { fontSize: '36px' },
},
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
{/* Your app here */}
</MantineProvider>
);
}
Theme 속성
autoContrast
autoContrast는 주어진 color prop에 따라 텍스트 색상이 바뀌어야 하는지를 다음 컴포넌트에서 제어해요:
-
variant="filled"인 ActionIcon만 -
variant="filled"인 Alert만 -
variant="filled"인 Avatar만 -
variant="filled"인 Badge만 -
variant="filled"인 Button만 -
variant="filled"인 Chip만 -
variant="filled"인 NavLink만 -
variant="filled"인 ThemeIcon만 -
variant="filled"인 Checkbox만 -
variant="filled"인 Radio만 -
variant="pills"인 Tabs만 -
SegmentedControl
-
Stepper
-
Pagination
-
Progress
-
Indicator
-
Timeline
-
Spotlight
-
Calendar 컴포넌트를 기반으로 하는 모든 @mantine/dates 컴포넌트
autoContrast는 주어진 색상의 휘도(luminosity)가 luminanceThreshold 값보다 높은지 낮은지 확인하고 그에 따라 텍스트 색상을 theme.white 또는 theme.black으로 바꿔요.
autoContrast는 Spotlight와 @mantine/dates 컴포넌트를 제외하고 theme 수준에서 전역으로 또는 각 컴포넌트에 autoContrast prop으로 개별적으로 설정할 수 있어요. 이 컴포넌트들은 전역 theme 설정만 지원해요.
import { Button, Code, Group } from '@mantine/core';
function Demo() {
return (
<>
<Group>
<Code>autoContrast: true</Code>
<Button color="lime.4">Lime.4 button</Button>
<Button color="blue.2">Blue.2 button</Button>
<Button color="orange.3">Orange.3 button</Button>
</Group>
<Group>
<Code>autoContrast: false</Code>
<Button color="lime.4" autoContrast={false}>Lime.4 button</Button>
<Button color="blue.2" autoContrast={false}>Blue.2 button</Button>
<Button color="orange.3" autoContrast={false}>Orange.3 button</Button>
</Group>
</>
);
}
luminanceThreshold
luminanceThreshold는 텍스트 색상이 밝아야 할지 어두워야 할지 결정하는 데 어떤 휘도 값이 사용되는지 제어해요. theme.autoContrast가 true로 설정된 경우에만 사용돼요. 기본값은 0.3이에요.
import { Button, createTheme, MantineProvider, Stack } from '@mantine/core';
const theme = createTheme({
autoContrast: true,
luminanceThreshold: 0.3,
});
function Wrapper(props: any) {
const buttons = Array(10)
.fill(0)
.map((_, index) => (
<Button key={index} color={`red.${index}`}>Button</Button>
));
return (
<Stack>{buttons}</Stack>
);
}
focusRing
theme.focusRing는 focus ring 스타일을 제어하며 다음 값을 지원해요:
-
auto(기본값 및 권장) – focus ring은 사용자가 키보드로 탐색할 때만 보여요. 이것은 네이티브 인터랙티브 요소의 기본 브라우저 동작이에요 -
always– focus ring은 사용자가 키보드와 마우스로 탐색할 때 보여요. 예를 들어 사용자가 버튼을 클릭할 때 focus ring이 보이고요 -
never– focus ring이 항상 숨겨져요; 권장되지 않아요 – 키보드로 탐색하는 사용자는 현재 포커스된 요소를 시각적으로 알 수 없게 돼요
focusClassName
theme.focusClassName은 Button이나 ActionIcon처럼 focus 스타일이 있는 요소에 추가되는 CSS 클래스예요. input을 제외한 모든 인터랙티브 컴포넌트의 focus ring 스타일을 커스터마이즈하는 데 사용할 수 있어요. theme.focusClassName이 설정되면 theme.focusRing은 무시된다는 점에 주의하세요.
import { MantineProvider, Button } from '@mantine/core';
import classes from './focus.module.css';
function Demo() {
return (
<MantineProvider theme={{ focusClassName: classes.focus }}>
<Button>Click button to see custom focus ring</Button>
</MantineProvider>
);
}
:focus-visible selector
:focus-visible 선택자는 91% 이상의 브라우저(2023년 4월 기준 데이터)에서 지원돼요. Safari 브라우저는 15.4 버전(2022년 3월 출시)에서 지원을 추가했어요. Safari 15.3 이하를 지원해야 한다면 focus-visible polyfill을 사용하거나 :focus pseudo-class로 fallback을 제공할 수 있어요.
activeClassName
theme.activeClassName은 Button이나 ActionIcon처럼 active 스타일이 있는 요소에 추가되는 CSS 클래스예요. 모든 인터랙티브 컴포넌트의 active 스타일을 커스터마이즈하는 데 사용할 수 있어요.
import { MantineProvider, Button } from '@mantine/core';
import classes from './active.module.css';
function Demo() {
return (
<MantineProvider theme={{ activeClassName: classes.active }}>
<Button>Press me to see active styles</Button>
</MantineProvider>
);
}
모든 컴포넌트의 active 스타일을 비활성화하려면 theme.activeClassName을 빈 문자열로 설정해요:
import { MantineProvider, Button } from '@mantine/core';
function Demo() {
return (
<MantineProvider theme={{ activeClassName: '' }}>
<Button>No active styles</Button>
</MantineProvider>
);
}
defaultRadius
theme.defaultRadius는 Button이나 TextInput 같은 대부분의 컴포넌트에서 기본 border-radius 속성을 제어해요. theme.radius의 값 중 하나로 설정하거나 정확한 값을 사용하기 위해 숫자/문자열로 설정할 수 있어요. 숫자는 픽셀로 취급되지만 rem으로 변환된다는 점에 주의하세요. 예를 들어 theme.defaultRadius: 4는 0.25rem으로 변환돼요. rem 변환에 대해 더 자세히 알아보려면 rem units 가이드를 참고하세요.
import { MantineProvider, TextInput, Button } from '@mantine/core';
function Demo() {
return (
<MantineProvider theme={{ defaultRadius: 'lg' }}>
<Button>Button with defaultRadius</Button>
</MantineProvider>
);
}
cursorType
theme.cursorType은 기본적으로 cursor: pointer 스타일이 없는 인터랙티브 요소의 기본 커서 타입을 제어해요. 예를 들어 Checkbox와 NativeSelect.
import { MantineProvider, createTheme, Checkbox } from '@mantine/core';
const theme = createTheme({
cursorType: 'pointer',
});
function Demo() {
return (
<MantineProvider theme={theme}>
<Checkbox label="Pointer cursor" />
</MantineProvider>
);
}
defaultGradient
theme.defaultGradient는 variant="gradient"를 지원하는 컴포넌트(Button, ActionIcon, Badge 등)의 기본 gradient 구성을 제어해요.
import { MantineProvider, createTheme, Button } from '@mantine/core';
const theme = createTheme({
defaultGradient: {
from: 'orange',
to: 'red',
deg: 45,
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
<Button variant="gradient">Button with custom default gradient</Button>
</MantineProvider>
);
}
fontWeights
theme.fontWeights는 모든 컴포넌트에서 사용되는 font-weight 값을 제어해요. 기본값은 regular: 400, medium: 600, bold: 700이에요. 각 값은 CSS 변수에 매핑돼요: --mantine-font-weight-regular, --mantine-font-weight-medium, --mantine-font-weight-bold.
예를 들어 medium font weight를 600에서 500(Mantine 8의 기본값)으로 되돌리려면:
import { createTheme, MantineProvider } from '@mantine/core';
const theme = createTheme({
fontWeights: {
medium: '500',
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
{/* Your app here */}
</MantineProvider>
);
}
components
theme.components는 컴포넌트의 기본 props와 classNames 및 styles 속성으로 스타일을 재정의할 수 있게 해줘요. 이 기능들에 대해 더 자세히 알아보려면 기본 props와 Styles API 가이드를 참고하세요.
other
theme.other는 theme 객체로 접근하고 싶은 다른 속성을 저장하는 데 사용할 수 있는 객체예요.
import { createTheme, MantineProvider } from '@mantine/core';
const theme = createTheme({
other: {
charcoal: '#333333',
primaryHeadingSize: 45,
fontWeights: {
bold: 700,
extraBold: 900,
},
},
});
function Demo() {
return (
<MantineProvider theme={theme}>
{/* Your app here */}
</MantineProvider>
);
}
theme override 객체를 변수에 저장
theme override 객체를 변수에 저장하려면 createTheme 함수를 사용해요:
import { createTheme, MantineProvider } from '@mantine/core';
const myTheme = createTheme({
primaryColor: 'orange',
defaultRadius: 0,
});
function Demo() {
return (
<MantineProvider theme={myTheme}>
{/* Your app here */}
</MantineProvider>
);
}
여러 theme override 병합
mergeThemeOverrides 함수를 사용해 여러 theme을 하나의 theme override 객체로 병합해요:
import {
createTheme,
MantineProvider,
mergeThemeOverrides,
} from '@mantine/core';
const theme1 = createTheme({
primaryColor: 'orange',
defaultRadius: 0,
});
const theme2 = createTheme({
cursorType: 'pointer',
});
// Note: It is better to store the theme override outside of the component body
// to prevent unnecessary re-renders
const myTheme = mergeThemeOverrides(theme1, theme2);
function Demo() {
return (
<MantineProvider theme={myTheme}>
{/* Your app here */}
</MantineProvider>
);
}
use-mantine-theme 훅
useMantineTheme 훅은 MantineProvider 컨텍스트에서 theme 객체를 반환해요:
import { useMantineTheme } from '@mantine/core';
function Demo() {
const theme = useMantineTheme();
return <div style={{ color: theme.colors.blue[6] }}>Text</div>;
}
기본 theme
@mantine/core 패키지에서 기본 theme 객체를 import 할 수 있어요. 기본값을 가진 모든 theme 속성이 포함돼 있어요. MantineProvider에 theme override를 전달하면 기본 theme과 깊게 병합돼요.
import { DEFAULT_THEME } from '@mantine/core';
컴포넌트 밖에서 theme 접근
컴포넌트 밖에서 theme에 접근하려면 전체 theme 객체(theme override와 기본 theme이 병합된 것)를 만들어야 해요.
// theme.ts
import {
createTheme,
DEFAULT_THEME,
mergeMantineTheme,
} from '@mantine/core';
const themeOverride = createTheme({
primaryColor: 'orange',
defaultRadius: 0,
});
export const theme = mergeMantineTheme(DEFAULT_THEME, themeOverride);
그러면 애플리케이션 어디서든 import 할 수 있어요:
import { theme } from './theme';