색상 체계
색상 체계 (Color schemes)
MantineProvider는 애플리케이션에서 색상 체계(color scheme) 컨텍스트를 관리해요. defaultColorScheme prop으로 기본 색상 체계 값을 구성할 수 있어요; 가능한 값은 light, dark, auto(시스템 색상 체계 사용)예요. 기본값은 light예요.
import { MantineProvider } from '@mantine/core';
function Demo() {
return (
<MantineProvider defaultColorScheme="light">
{/* Your app here */}
</MantineProvider>
);
}
출처: 문서
본문
data-mantine-color-scheme 속성
MantineProvider가 마운트되면 사용자가 이전에 선택한 값이나 defaultColorScheme prop의 값으로 `` 요소에 data-mantine-color-scheme 속성을 설정해요. data-mantine-color-scheme 속성은 모든 컴포넌트 스타일에서 각 컴포넌트가 어떤 색상을 사용할지 결정하는 데 사용돼요.
use-mantine-color-scheme 훅
useMantineColorScheme 훅은 현재 색상 체계 값을 가져오고 설정하는 데 사용할 수 있어요:
function useMantineColorScheme(): {
/** Current color scheme value */
colorScheme: 'dark' | 'light' | 'auto';
/** Sets colors scheme to given value */
setColorScheme: (colorScheme: 'dark' | 'light' | 'auto') => void;
/** Toggles color scheme to the opposite value; if value is 'auto', color scheme is inferred from the OS settings */
toggleColorScheme: () => void;
/** Clears the color scheme value from storage and sets it to `defaultColorScheme` */
clearColorScheme: () => void;
};
import { useMantineColorScheme, Button, Group } from '@mantine/core';
function Demo() {
const { setColorScheme, clearColorScheme } = useMantineColorScheme();
return (
<Group>
<Button onClick={() => setColorScheme('light')}>Light</Button>
<Button onClick={() => setColorScheme('dark')}>Dark</Button>
<Button onClick={() => setColorScheme('auto')}>Auto</Button>
<Button onClick={clearColorScheme}>Clear</Button>
</Group>
);
}
use-computed-color-scheme 훅
useComputedColorScheme은 계산된 색상 체계 값(light 또는 dark)을 반환해요. 색상 체계 토글 로직을 구현하는 데 사용할 수 있어요:
import {
useComputedColorScheme,
useMantineColorScheme,
} from '@mantine/core';
function Demo() {
// -> colorScheme is 'auto' | 'light' | 'dark'
const { colorScheme, setColorScheme } = useMantineColorScheme();
// -> computedColorScheme is 'light' | 'dark', argument is the default value
const computedColorScheme = useComputedColorScheme('light');
// Incorrect color scheme toggle implementation
// If colorScheme is 'auto', then it is not possible to
// change color scheme correctly in all cases:
// 'auto' can mean both light and dark
const toggleColorScheme = () => {
setColorScheme(colorScheme === 'dark' ? 'light' : 'dark');
};
// Correct color scheme toggle implementation
// computedColorScheme is always either 'light' or 'dark'
const toggleColorScheme = () => {
setColorScheme(computedColorScheme === 'dark' ? 'light' : 'dark');
};
}
색상 체계 변경 중 전환(transition)
기본적으로 색상 체계가 바뀔 때 모든 요소의 전환이 비활성화되어 일관되지 않은 애니메이션을 방지해요. 색상 체계 변경 중 전환을 활성화하려면 useMantineColorScheme 훅에서 keepTransitions: true 옵션을 설정해요:
import { useMantineColorScheme } from '@mantine/core';
function Demo() {
const { colorScheme, setColorScheme } = useMantineColorScheme({
keepTransitions: true,
});
}
색상 체계 값 주의사항
기본적으로 색상 체계 값은 local storage에 저장되며, 부정확한 색상 체계의 깜빡임(flash)을 피하기 위해 컴포넌트가 마운트되기 전에 값이 state에 저장돼요. 즉 색상 체계 값은 클라이언트와 서버에서 다를 수 있는데, 서버는 local storage에 접근할 수 없고 항상 기본값을 사용하기 때문이에요.
애플리케이션에 서버 사이드 렌더링이 있다면(예: Next.js나 React Router 사용) hydration 문제를 피하기 위해 애플리케이션에서 colorScheme 값을 사용할 수 없어요. 대신 postcss-preset-mantine의 dark와 light 믹스인을 사용해 색상 체계 값에 따라 요소를 숨기는 스타일을 생성할 수 있어요:
import { ActionIcon, useMantineColorScheme, useComputedColorScheme } from '@mantine/core';
import { SunIcon, MoonIcon } from '@phosphor-icons/react';
import cx from 'clsx';
import classes from './Demo.module.css';
function Demo() {
const { setColorScheme } = useMantineColorScheme();
const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true });
return (
<ActionIcon
onClick={() => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')}
variant="default"
size="xl"
aria-label="Toggle color scheme"
>
{computedColorScheme === 'light' ? <MoonIcon /> : <SunIcon />}
</ActionIcon>
);
}
클라이언트 전용 애플리케이션의 colorScheme
colorScheme 값을 클라이언트 전용 애플리케이션(예: Vite나 create-react-app)에서는 안전하게 사용할 수 있어요. 이 경우 hydration이 없으므로 hydration 오류도 발생할 수 없어요.
ColorSchemeScript
ColorSchemeScript 컴포넌트는 hydration 전에 `` 요소의 data-mantine-color-scheme 속성을 사용자가 선택한 값이나 defaultColorScheme prop 값으로 설정하는 script 태그를 렌더링해요. 서버 사이드 렌더링 애플리케이션, 예를 들어 Next.js나 React Router에서 부정확한 색상 체계의 깜빡임을 피하는 데 사용돼요. ColorSchemeScript 컴포넌트를 어디에 렌더링할지는 프레임워크별 가이드를 따라 알아보세요.
ColorSchemeScript 컴포넌트가 생성한 `` 태그에 nonce 속성 같은 추가 props를 더할 수 있어요:
import { ColorSchemeScript } from '@mantine/core';
function Demo() {
return (
<ColorSchemeScript nonce="8IBTHwOdqNKA" />
);
}
자동 색상 체계
시스템 색상 체계를 사용하려면 MantineProvider와 ColorSchemeScript에 defaultColorScheme="auto"를 설정해요. 이 경우 색상 체계 값은 사용자의 OS가 제어해요:
import { ColorSchemeScript, MantineProvider } from '@mantine/core';
function Demo() {
return (
<>
<ColorSchemeScript defaultColorScheme="auto" />
<MantineProvider defaultColorScheme="auto">
{/* Your app here */}
</MantineProvider>
</>
);
}
색상 체계 매니저
기본적으로 색상 체계 값은 local storage에 저장되지만, 값을 다른 외부 저장소에 저장하는 나만의 색상 체계 매니저를 구현할 수 있어요.
색상 체계 매니저는 다음 메서드를 가져야 해요:
interface MantineColorSchemeManager {
/** Function to retrieve color scheme value from external storage, for example window.localStorage */
get: (defaultValue: MantineColorScheme) => MantineColorScheme;
/** Function to set color scheme value in external storage, for example window.localStorage */
set: (value: MantineColorScheme) => void;
/** Function to subscribe to color scheme changes triggered by external events */
subscribe: (
onUpdate: (colorScheme: MantineColorScheme) => void
) => void;
/** Function to unsubscribe from color scheme changes triggered by external events */
unsubscribe: () => void;
/** Function to clear value from external storage */
clear: () => void;
}
보통 색상 체계 매니저를 구성할 방법을 제공하기 위해 creator 함수로 감싸는 것이 좋아요. 기본 local storage 기반 색상 체계 매니저 예시:
import {
isMantineColorScheme,
MantineColorScheme,
MantineColorSchemeManager,
} from '@mantine/core';
export interface LocalStorageColorSchemeManagerOptions {
/** Local storage key used to retrieve value with `localStorage.getItem(key)`, `mantine-color-scheme` by default */
key?: string;
}
export function localStorageColorSchemeManager({
key = 'mantine-color-scheme',
}: LocalStorageColorSchemeManagerOptions = {}): MantineColorSchemeManager {
let handleStorageEvent: (event: StorageEvent) => void;
return {
get: (defaultValue) => {
if (typeof window === 'undefined') {
return defaultValue;
}
try {
return (
(window.localStorage.getItem(key) as MantineColorScheme) ||
defaultValue
);
} catch {
return defaultValue;
}
},
set: (value) => {
try {
window.localStorage.setItem(key, value);
} catch (error) {
// eslint-disable-next-line no-console
console.warn(
'[@mantine/core] Local storage color scheme manager was unable to save color scheme.',
error
);
}
},
subscribe: (onUpdate) => {
handleStorageEvent = (event) => {
if (
event.storageArea === window.localStorage &&
event.key === key
) {
isMantineColorScheme(event.newValue) &&
onUpdate(event.newValue);
}
};
window.addEventListener('storage', handleStorageEvent);
},
unsubscribe: () => {
window.removeEventListener('storage', handleStorageEvent);
},
clear: () => {
window.localStorage.removeItem(key);
},
};
}
그런 다음 커스텀 색상 체계 매니저를 MantineProvider에 전달할 수 있어요:
import { MantineProvider } from '@mantine/core';
import { localStorageColorSchemeManager } from './localStorageColorSchemeManager';
const colorSchemeManager = localStorageColorSchemeManager({
key: 'my-color-scheme',
});
function Demo() {
return (
<MantineProvider colorSchemeManager={colorSchemeManager}>
{/* Your app here */}
</MantineProvider>
);
}
기본 색상 체계
기본 색상 체계 값은 사용자가 아직 어떤 색상 체계도 선택하지 않았을 때 사용돼요. MantineProvider와 ColorSchemeScript 양쪽에 설정해야 해요. defaultColorScheme이 설정되지 않으면 light가 사용돼요.
import { ColorSchemeScript, MantineProvider } from '@mantine/core';
function Demo() {
return (
<>
<ColorSchemeScript defaultColorScheme="dark" />
<MantineProvider defaultColorScheme="dark">
{/* Your app here */}
</MantineProvider>
</>
);
}
색상 체계 강제
forceColorScheme prop으로 색상 체계 값을 light 또는 dark로 강제할 수 있어요. MantineProvider와 ColorSchemeScript 양쪽에 설정해야 해요. forceColorScheme이 설정되면 defaultColorScheme과 colorSchemeManager는 무시돼요. forceColorScheme이 설정되면 setColorScheme 함수로 색상 체계 값을 바꿀 수 없어요.
import { ColorSchemeScript, MantineProvider } from '@mantine/core';
function Demo() {
return (
<>
<ColorSchemeScript forceColorScheme="dark" />
<MantineProvider forceColorScheme="dark">
{/* Your app here */}
</MantineProvider>
</>
);
}
lightHidden, darkHidden props
모든 Mantine 컴포넌트는 특정 색상 체계에서 컴포넌트를 숨기는 데 사용할 수 있는 lightHidden과 darkHidden props를 지원해요:
import { Button } from '@mantine/core';
function Demo() {
return (
<>
<Button darkHidden>Visible in dark color scheme only</Button>
<Button lightHidden>Visible in light color scheme only</Button>
</>
);
}
JavaScript 비활성 상태
JavaScript가 비활성화된 사용자를 지원해야 한다면 `` 요소에 data-mantine-color-scheme 속성을 수동으로 설정해야 해요.
JavaScript 비활성 상태를 지원하는 Next.js app router 예시:
import '@mantine/core/styles.css';
import { ColorSchemeScript, MantineProvider } from '@mantine/core';
export const metadata = {
title: 'My Mantine app',
description: 'I have followed setup instructions carefully',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" data-mantine-color-scheme="light">
<head>
<ColorSchemeScript />
</head>
<body>
<MantineProvider>{children}</MantineProvider>
</body>
</html>
);
}