6.x → 7.x 마이그레이션 가이드

6.x → 7.x 마이그레이션 가이드

이 가이드는 프로젝트 스타일을 6.x에서 7.x로 마이그레이션하는 데 도움을 줘요. 7.x의 모든 변경 사항을 다루는 포괄적인 가이드는 아니에요. 전체 개요는 7.0.0 changelog를 참조하세요.

출처: 문서

본문

@mantine/emotion으로 마이그레이션

@mantine/emotion 패키지는 버전 7.9부터 사용할 수 있어요. CSS 모듈을 쓰고 싶지 않고, createStyles, sx, styles props로 만든 스타일이 많거나, CSS-in-JS 문법을 선호한다면 @mantine/emotion으로 마이그레이션할 수 있어요. @mantine/emotion 패키지의 전체 문서는 이 페이지에서 볼 수 있어요.

createStyles와 Global 컴포넌트

createStyles 함수와 Global 컴포넌트는 더 이상 @mantine/core 패키지에서 사용할 수 없어요. import를 @mantine/emotion으로 바꿔주세요:

// 6.x
import { createStyles, Global } from '@mantine/core';

// 7.x
import { createStyles, Global } from '@mantine/emotion';

sx와 styles props

@mantine/emotion 설정 후 sx와 styles props는 7.x에서 6.x와 같은 방식으로 사용할 수 있어요:

// 6.x and 7.x, no changes
import { Box, Button } from '@mantine/core';

function Demo() {
  return (
    <>
      <Box
        sx={(theme) => ({ backgroundColor: theme.colors.red[5] })}
      />
      <Button styles={{ root: { height: 50 } }} />
    </>
  );
}

theme.colorScheme

v7에서 color scheme 값은 MantineProvider가 관리하고, theme 객체에는 더 이상 colorScheme 속성이 포함되지 않아요. useMantineColorScheme 훅으로 컴포넌트에서 color scheme 값을 접근하는 것은 여전히 가능하지만, 스타일을 이 값에 기반하는 것은 권장하지 않아요. 대신 light/dark 유틸리티를 사용하세요.

theme.colorScheme이 있는 6.x createStyles를 7.0으로 마이그레이션한 예시:

// 6.x
import { createStyles } from '@mantine/core';

const useStyles = createStyles((theme) => ({
  root: {
    backgroundColor:
      theme.colorScheme === 'dark'
        ? theme.colors.dark[6]
        : theme.colors.gray[0],
    color: theme.colorScheme === 'dark' ? theme.white : theme.black,
  },
}));
// 7.x
import { createStyles } from '@mantine/emotion';

const useStyles = createStyles((theme, _, u) => ({
  root: {
    [u.dark] {
      backgroundColor: theme.colors.dark[6];
      color: theme.white;
    },

    [u.light]: {
      backgroundColor: theme.colors.gray[0];
      color: theme.black;
    },
  },
}));

CSS 모듈로 마이그레이션

시작하기 전에 스타일 문서를 살펴보는 것을 권장해요. 가장 중요한 섹션은 다음과 같아요:

  • CSS Modules
  • Mantine PostCSS preset
  • CSS 변수
  • data-* 속성
  • Styles API
  • 반응형 스타일

이 가이드는 프로젝트에 postcss-preset-mantine이 설치·설정되어 있다고 가정해요.

createStyles

createStyles 함수는 7.0에서 더 이상 사용할 수 없어요. 대신 CSS Modules를 사용하세요:

// 6.x
import { createStyles } from '@mantine/core';

const useStyles = createStyles((theme) => ({
  root: {
    backgroundColor: theme.colors.red[5],
  },
}));
/* 7.0 */
.root {
  background-color: var(--mantine-color-red-5);
}

sx prop

sx prop은 7.0에서 더 이상 사용할 수 없어요. className이나 style prop을 사용하세요:

// 6.x
import { Box } from '@mantine/core';

function Demo() {
  return (
    <Box sx={(theme) => ({ backgroundColor: theme.colors.red[5] })} />
  );
}
// 7.0
import { Box } from '@mantine/core';

function Demo() {
  return (
    <Box style={{ backgroundColor: 'var(--mantine-color-red-5)' }} />
  );
}

style prop은 중첩 선택자를 지원하지 않아요. 대신 className을 사용하세요:

// 6.x
import { Box } from '@mantine/core';

function Demo() {
  return <Box sx={{ '&:hover': { background: 'red' } }} />;
}
.box {
  &:hover {
    background: red;
  }
}

styles prop

styles prop은 더 이상 중첩 선택자를 지원하지 않아요. 중첩 요소에 스타일을 적용하려면 classNames를 사용하세요:

// 6.x – nested selectors
import { TextInput } from '@mantine/core';

function Demo() {
  return (
    <TextInput
      styles={{
        input: {
          '&:focus': {
            color: 'red',
          },
        },
      }}
    />
  );
}
/* 7.0 */
.input {
  &:focus {
    color: red;
  }
}

일반 선택자는 여전히 지원돼요:

// Works both in 6.x and 7.x
import { TextInput } from '@mantine/core';

function Demo() {
  return (
    <TextInput
      styles={{
        input: {
          color: 'red',
        },
      }}
    />
  );
}

전역 스타일 (Global styles)

Global 컴포넌트와 테마의 전역 스타일은 7.0에서 사용할 수 없어요. 대신 전역 스타일시트(.css 파일)를 만들고 애플리케이션 진입점에서 import하세요:

// 6.x
import { Global } from '@mantine/core';

function Demo() {
  return (
    <Global
      styles={(theme) => ({
        '*, *::before, *::after': {
          boxSizing: 'border-box',
        },

        body: {
          backgroundColor:
            theme.colorScheme === 'dark'
              ? theme.colors.dark[7]
              : theme.white,
          color:
            theme.colorScheme === 'dark'
              ? theme.colors.dark[0]
              : theme.black,
          lineHeight: theme.lineHeight,
        },

        '.your-class': {
          backgroundColor: 'red',
        },

        '#your-id > [data-active]': {
          backgroundColor: 'pink',
        },
      })}
    />
  );
}
/* 7.0 */
/* src/index.css */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  background-color: light-dark(
    var(--mantine-color-white),
    var(--mantine-color-dark-7)
  );
  color: light-dark(
    var(--mantine-color-black),
    var(--mantine-color-white)
  );
  line-height: var(--mantine-line-height);
}

.your-class {
  background-color: red;
}

#your-id > [data-active] {
  background-color: pink;
}

테마 참조 (theme referencing)

모든 theme 속성은 이제 CSS 변수로 제공돼요. 스타일에서 theme 객체를 참조하는 대신 CSS 변수를 사용하는 것을 권장해요:

// 6.x
import { Box } from '@mantine/core';

function Demo() {
  return (
    <Box
      sx={(theme) => ({
        backgroundColor: theme.colors.red[6],
        color: theme.white,
        padding: `calc(${theme.spacing.xl} * 2)`,
      })}
    />
  );
}
/* 7.0 */
.box {
  background-color: var(--mantine-color-red-6);
  color: var(--mantine-color-white);
  padding: calc(var(--mantine-spacing-xl) * 2);
}

theme.colorScheme

color scheme 값은 MantineProvider가 관리하고, theme 객체에는 더 이상 colorScheme 속성이 포함되지 않아요. useMantineColorScheme 훅으로 컴포넌트에서 color scheme 값을 접근하는 것은 가능하지만, 스타일을 이 값에 기반하는 것은 권장하지 않아요. 대신 light/dark 믹스인 또는 light-dark CSS 함수를 사용하세요.

theme.colorScheme이 있는 6.x createStyles를 7.0으로 마이그레이션한 예시:

// 6.x
import { createStyles } from '@mantine/core';

const useStyles = createStyles((theme) => ({
  root: {
    backgroundColor:
      theme.colorScheme === 'dark'
        ? theme.colors.dark[6]
        : theme.colors.gray[0],
    color: theme.colorScheme === 'dark' ? theme.white : theme.black,
  },
}));
/* 7.0 */

/* With light-dark function */
.root {
  background-color: light-dark(
    var(--mantine-color-gray-0),
    var(--mantine-color-dark-6)
  );
  color: light-dark(
    var(--mantine-color-black),
    var(--mantine-color-white)
  );
}

/* With light/dark mixins */
.root {
  background-color: var(--mantine-color-gray-0);
  color: var(--mantine-color-black);

  @mixin dark {
    background-color: var(--mantine-color-dark-6);
    color: var(--mantine-color-white);
  }
}

애플리케이션에 서버 사이드 렌더링이 있다면 color scheme 값에 기반해 어떤 요소도 렌더링하면 안 돼요(자세한 정보). 대신 light/dark 믹스인 또는 light-dark 함수를 사용해 color scheme 값에 따라 요소를 숨기거나 표시하세요.

color scheme 토글 예시:

/* Demo.module.css */
.icon {
  width: 22px;
  height: 22px;
}

.dark {
  @mixin light {
    display: none;
  }
}

.light {
  @mixin dark {
    display: none;
  }
}
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"
    >
      <SunIcon className={cx(classes.icon, classes.light)} />
      <MoonIcon className={cx(classes.icon, classes.dark)} />
    </ActionIcon>
  );
}

더 알아보기 (Learn more)