Right-to-left support
Right-to-left support (RTL 지원)
아랍어, 페르시아어, 히브리어 같은 RTL(right-to-left) 언어를 지원하기 위해 Material UI에서 오른쪽에서 왼쪽으로 쓰는 텍스트를 구현하는 방법을 배워봐요.
출처: 문서
본문
Setup (설정)
이 가이드에서는 Material UI의 텍스트 기반 컴포넌트 방향을 RTL 언어를 지원하도록 바꾸는 데 필요한 세 가지 단계를 설명해요. 아래 데모에서 볼 수 있듯이요:
import { createTheme, ThemeProvider, Theme } from '@mui/material/styles';
import TextField from '@mui/material/TextField';
import rtlPlugin from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
// Consuming the outer theme is only required with coexisting themes, like in this documentation.
// If your app/website doesn't deal with this, you can have just:
// const theme = createTheme({ direction: 'rtl' })
const theme = (outerTheme: Theme) =>
createTheme({
direction: 'rtl',
palette: {
mode: outerTheme.palette.mode,
},
});
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
export default function RtlDemo() {
return (
<CacheProvider value={cacheRtl}>
<ThemeProvider theme={theme}>
<div dir="rtl">
<TextField
label="ملصق"
placeholder="العنصر النائب"
helperText="هذا نص مساعد"
variant="outlined"
/>
</div>
</ThemeProvider>
</CacheProvider>
);
}
1. Set the HTML direction (HTML 방향 설정)
텍스트 방향은 사용 사례에 따라 전역(앱 전체)으로 설정하거나 로컬(개별 컴포넌트만)로 설정할 수 있어요.
Globally (전역으로)
앱의 루트 <html>에 dir="rtl"을 추가해서 전체 텍스트 방향을 설정해요:
<html dir="rtl"></html>
루트 <html> 요소에 직접 dir 속성을 설정할 수 없다면, 페이지가 렌더링되기 전에 JavaScript API를 사용하는 방법이 있어요:
document.documentElement.setAttribute('dir', 'rtl');
Locally (로컬로)
텍스트 방향의 범위를 특정 요소와 그 자식들로 제한해야 한다면, 다른 HTML 요소나 React 컴포넌트에 dir="rtl" 속성을 추가하면 돼요.
:::warning
React 포털(portal)을 사용하는 컴포넌트(예: Dialog)는 실제로 부모 DOM 트리 밖에 렌더링되기 때문에 부모로부터 dir 속성을 상속받지 않아요.
이 컴포넌트들이 전역으로 오른쪽에서 왼쪽(RTL)으로 정의되어 있지 않다면, 이런 컴포넌트에 dir 속성을 직접 적용해야 해요:
<Box dir="rtl">
<Dialog /> // ❌ this Dialog will still be left-to-right (the default)
</Box>
<Box dir="rtl">
<Dialog dir="rtl" /> // ✅ this Dialog will be right-to-left as intended
</Box>
:::
2. Set the theme direction (테마 방향 설정)
createTheme() API를 사용해서 테마 방향을 'rtl'로 설정해요:
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
direction: 'rtl',
});
3. Configure RTL style plugin (RTL 스타일 플러그인 구성)
아래 명령 중 하나를 사용해서 @mui/stylis-plugin-rtl을 설치해요:
npm install stylis @mui/stylis-plugin-rtl
pnpm add stylis @mui/stylis-plugin-rtl
yarn add stylis @mui/stylis-plugin-rtl
With Emotion (Emotion 사용 시)
Emotion을 사용하고 있다면, CacheProvider를 사용해서 @mui/stylis-plugin-rtl의 rtlPlugin을 사용하는 새로운 캐시 인스턴스를 만들고, 이를 애플리케이션 트리 맨 위에 추가해요:
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { prefixer } from 'stylis';
import rtlPlugin from '@mui/stylis-plugin-rtl';
// Create rtl cache
const rtlCache = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
function Rtl(props) {
return <CacheProvider value={rtlCache}>{props.children}</CacheProvider>;
}
With styled-components (styled-components 사용 시)
styled-components를 사용하고 있다면, StyleSheetManager를 사용해서 stylisPlugins 속성에 rtlPlugin을 제공해요:
import { StyleSheetManager } from 'styled-components';
import rtlPlugin from '@mui/stylis-plugin-rtl';
function Rtl(props) {
return (
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
{props.children}
</StyleSheetManager>
);
}
Opting out of RTL locally (로컬에서 RTL 제외하기)
특정 컴포넌트에서 RTL을 끄려면 템플릿 리터럴(template literal) 문법을 사용하고 /* @noflip */ 지시문을 추가해요:
const LeftToRightTextInRtlApp = styled('div')`
/* @noflip */
text-align: left;
`;
import * as React from 'react';
import { prefixer } from 'stylis';
import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';
const Normal = styled('div')`
text-align: left;
`;
const Noflip = styled('div')`
/* @noflip */
text-align: left;
`;
const rtlCache = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
const ltrCache = createCache({
key: 'mui',
});
export default function RtlOptOut() {
const [rtl, setRtl] = React.useState(false);
const handleChange = () => {
setRtl(!rtl);
};
return (
<Box sx={{ width: '100%', display: 'flex' }}>
<FormControlLabel
control={<Switch onChange={handleChange} />}
label="Toggle RTL"
/>
<CacheProvider value={rtl ? rtlCache : ltrCache}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : undefined}>
<Normal>RTL normal behavior</Normal>
<Noflip>RTL noflip</Noflip>
</Box>
</CacheProvider>
</Box>
);
}
더 알아보기 (Learn more)
- @mui/stylis-plugin-rtl — RTL 스타일 처리를 위한 stylis 플러그인
- Emotion CacheProvider — Emotion 캐시 인스턴스 문서
- styled-components StyleSheetManager — styled-components 스타일 시트 관리 문서