如何为 Material UI React 添加 RTL 支持

2024-04-07

我正在构建一个 LTR 应用程序,并且想添加 RTL 支持。 该应用程序基于 Material UI React 之上。 由于我使用的是 CSS Flex Box,因此我能够将应用程序旋转到 RTL,只需将 dir="rtl" 添加到主体即可。我还在主题中添加了 Direction="rtl" ,如上所述here https://material-ui.com/guides/right-to-left/.

然而,并不是一切都改变了。

Let's take this as an example : Select Country LTR As you can see here I have padding left to the text element. In the RTL version, since everything was reversed the padding left has no effect in the UI, I mean it must be padding right to show the small space between the two element : Select Country RTL

看来我做错了什么,因为在 Material UI 文档中here https://material-ui.com/guides/right-to-left/#3-jss-rtl添加此代码片段并将组件包裹在其周围后,此功能必须是开箱即用的。

这是我的父组件应用程序:

import React, { PureComponent } from "react";
import { theme } from "./styling/theme";
import Routes from "./Routes";
// Redux
import { Provider } from "react-redux";
import store from "./app/store";

import LoadingBar from "react-redux-loading-bar";
// CSS
import { MuiThemeProvider } from "@material-ui/core/styles";
// import { ThemeProvider } from "@material-ui/styles";
import { create } from "jss";
import rtl from "jss-rtl";
import JssProvider from "react-jss/lib/JssProvider";
// import { StylesProvider, jssPreset } from "@material-ui/styles";
import { createGenerateClassName, jssPreset } from "@material-ui/core/styles";
import { themeObject, colors } from "./styling/theme";
// Helpers
import get from "lodash/get";

// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const generateClassName = createGenerateClassName();

function RTL(props) {
  return (
    <JssProvider jss={jss} generateClassName={generateClassName}>
      {
        props.children
      }
    </JssProvider>
  );
}

class App extends PureComponent {
  render() {
    const isRtl = get(store, "classified.language.rtl", false);
    return (
      <Provider store={store}>
        <RTL>
          <MuiThemeProvider
            theme={
              isRtl
                ? { ...theme, direction: "rtl" }
                : { ...theme, direction: "ltr" }
            }
          >
            <LoadingBar
              style={{
                backgroundColor: colors.primary[500],
                height: themeObject.spacing.unit,
                zIndex: 9999
              }}
            />
            <Routes />
          </MuiThemeProvider>
        </RTL>
      </Provider>
    );
  }
}

export default App;

这是我的组件的示例(上图中的组件:CLList):

import React, { Component } from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
// Helpers
import isFunction from "lodash/isFunction";
import cloneDeep from "lodash/cloneDeep";

import styles from "./CLList.styles";

const defaultImg = "IMAGE_URL_HERE";
class CLList extends Component {
  static propTypes = {
    classes: PropTypes.object.isRequired,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        img: PropTypes.string,
        name: PropTypes.string
      })
    ).isRequired,
    onClick: PropTypes.func
  };
  render() {
    const { classes, items, onClick } = this.props;
    return (
      <ul className={classes.list}>
        {items.map((item, key) => (
          <li
            className={classes.item}
            onClick={() => isFunction(onClick) && onClick(cloneDeep(item))}
            key={key}
          >
            <img
              className={classes.image}
              src={item.img || defaultImg}
              alt={item.name}
              title={item.name}
            />
            <span className={classes.label}>{item.name}</span>
          </li>
        ))}
      </ul>
    );
  }
}

export default withStyles(styles)(CLList);

最后一个文件是 CLList 的 CSS:

import { colors } from "../..";
const styles = theme => ({
  list: {
    display: "flex",
    flexDirection: "column",
    listStyle: "none",
    padding: 5,
    margin: 0,
    "& > li:not(:last-child)": {
      marginBottom: 10
    }
  },
  item: {
    flex: 1,
    display: "flex",
    cursor: "pointer",
    "&:hover": {
      backgroundColor: colors.primary[50]
    }
  },
  image: {
    flex: "0 0 15%",
    maxWidth: "40px",
    maxHeight: "40px"
  },
  label: {
    flex: "1",
    alignSelf: "center",
    paddingLeft: 20
  }
});

export default styles;

我期望标签的 paddingLeft => paddingRight。这可能吗 ?这是一个开箱即用的功能吗?或者我应该使用RTL-CSS-JS https://github.com/kentcdodds/rtl-css-js并在正文包含 dir="RTL" 时包装所有样式对象以自动更改样式?

我对这两个库也很困惑:

  • @material-ui/核心/样式
  • @material-ui/样式

我应该使用第一个还是第二个?有什么不同 ?

谢谢你的时间。

EDIT 1 :

I used rtlCSSJS在我的 CSS 对象上,我得到了预期的结果。但我不确定这是否是最好的方法。 CLList 的 CSS 现在看起来像这样:

import rtlCSSJS from "rtl-css-js";
import { colors } from "../..";
const defaultDir = document.body.getAttribute("dir");
const styles = theme =>
  defaultDir === 'rtl' ? rtlCSSJS({...CSS_HERE....}) : {...CSS_HERE....};
export default styles;

我想我找到了自己问题的解决方案,但是请随意添加任何增强功能或更好的解决方案。

Material UI 默认使用 jss-rtl,最后一个是 rtl-css-js 的包装器。因此不需要直接使用 rtl-css-js,因为 Material UI 会完成这项工作。

我将我的父应用程序组件更改为:

import React, { PureComponent } from "react";
import Routes from "./Routes";
import RTL from "./RTL";
// Redux
import { Provider } from "react-redux";
import store from "./app/store";

import LoadingBar from "react-redux-loading-bar";

import { themeObject, colors } from "./styling/theme";

class App extends PureComponent {
  render() {
    return (
      <Provider store={store}>
        <RTL>
          <>
            <LoadingBar
              // className="loading"
              style={{
                backgroundColor: colors.primary[500],
                height: themeObject.spacing.unit,
                zIndex: 9999
              }}
            />
            <Routes />
          </>
        </RTL>
      </Provider>
    );
  }
}

export default App;

我添加了 RTL 组件,它将连接到 Redux,以正确的方向定义正确的主题。我将语言数据保存在 Redux 中,并根据此数据我将定义为我的应用程序提供的主题。

这是 RTL 组件:

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
// Redux
import { connect } from "react-redux";
// CSS
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles";
import { create } from "jss";
import rtl from "jss-rtl";
import JssProvider from "react-jss/lib/JssProvider";
import { createGenerateClassName, jssPreset } from "@material-ui/core/styles";

// Theme
import { themeObject } from "./styling/theme";

// Helpers
import get from "lodash/get";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const generateClassName = createGenerateClassName();

const G_isRtl = document.body.getAttribute("dir") === "rtl";

class RTL extends PureComponent {
  static propTypes = {
    children: PropTypes.oneOfType([
      PropTypes.array,
      PropTypes.object,
      PropTypes.node
    ]),
    language: PropTypes.object
  };

  render() {
    const { children, language } = this.props;
    const isRtl = get(language, "rtl", G_isRtl);

    const theme = createMuiTheme({
      ...themeObject,
      direction: isRtl ? "rtl" : "ltr"
    });

    return (
      <JssProvider jss={jss} generateClassName={generateClassName}>
        <MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
      </JssProvider>
    );
  }
}

const mapStateToProps = ({ classified }) => ({
  language: classified.language
});
export default connect(mapStateToProps)(RTL);

现在所有的子组件都会根据语言在 RTL 和 LTR 之间切换,我们可以只关注一种布局,所有的逆向工作都是通过这个插件完成的。

另外我想说的是按照官方的说明进行操作文档 https://material-ui.com/guides/right-to-left/#3-jss-rtl对我不起作用!我找到的大部分解决方案都是基于答案here https://stackoverflow.com/questions/49805381/material-ui-jss-rtl-after-using-jss-rtl-my-page-is-still-ltr/50426110#50426110.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为 Material UI React 添加 RTL 支持 的相关文章

随机推荐

  • 如何使用Watin / IE9测试文件下载?

    我正在尝试使用 Watin 2 1 0 针对 IE9 测试文件下载 我使用了问题已接受答案中的建议代码在 IE9 中使用 Watin 下载文件 https stackoverflow com questions 6125285 downlo
  • 在 Hadoop MapReduce 中解析 PDF 文件

    我必须在 Hadoop 的 MapReduce 程序中解析 HDFS 中的 PDF 文件 所以我从 HDFS 获取 PDF 文件为输入分割它必须被解析并发送到 Mapper 类 为了实现这个输入格式我已经经历过这个link http cod
  • 属性错误“模块”对象没有属性“DateField”

    我试图在 Satchmo Django 中扩展管理定义 并在尝试向 ProductOptions 添加 formfield override 时收到错误 属性错误 模块 对象没有属性 DateField from django contri
  • quartz 默认线程数是多少

    我是新来的Quartz 我确实设法弄清楚调度程序配置的默认值是org quartz threadPool threadCount 1 但它没有在任何地方找到这意味着什么 这是否意味着只有一个线程或者有其他 数字 我正在使用quartz sc
  • 如何使用蓝图将 Flasgger 与 Flask 应用程序结合使用?

    我正在使用以下命令将 Swagger UI 添加到我的 Python Flask 应用程序中Flasgger https github com rochacbruno flasgger 互联网上最常见的示例是使用基本 Flask 风格 ap
  • 使用 VS2017 启动 asp.net core 应用程序会创建新的应用程序池

    每次当我在 VS2017 的本地 IIS 下启动 ASP net Core 应用程序的调试器时 都会创建一个新的应用程序池 我希望应用程序在 DefaultAppPool 身份 下保持稳定 而不是创建新的应用程序 这个设置在哪里会影响这个
  • Laravel 查询带有“if”条件?

    我正在尝试使用 Laravel 4 制作高级搜索表单 这是查询 result DB table users ads gt join ads users ads ad id ads id gt orderBy column method gt
  • JavaScript 通过引用与通过值 [重复]

    这个问题在这里已经有答案了 我正在寻找一些很好的综合阅读材料 了解 JavaScript 何时按值传递内容 何时通过引用传递内容 何时修改传递的项目影响函数外部的值以及何时不影响函数外部的值 我还感兴趣的是 何时通过引用与通过值分配给另一个
  • 相邻弹性盒容器中的内容垂直对齐

    我有多个项目说卡片 这些卡片需要水平堆叠 并且高度需要相同 这正在发生在我身上 每张卡片都有图像 文本和按钮 每张卡片的图像和文本应采用任何卡片的最大高度 以便它们正确对齐 这不会发生在我身上 如果图像和文本正确对齐 则按钮将始终在底部的每
  • Firestore安全规则:在文档的数组中搜索用户的ID

    首先 对不起我糟糕的英语 这不是我的母语 我正在 Firebase 中使用 Firestore 数据库构建一个简单的应用程序 在我的应用程序中 用户是小组的成员 他们可以访问其他用户的数据 为了不查询太多文档 每个用户一个 在组文档的子集合
  • 循环 AVMutableCompositionTrack

    我身上有两个音轨 我将它们相互组合起来 如下所示 AVMutableComposition composition AVMutableComposition alloc init AVMutableCompositionTrack comp
  • Python 获取系统环境变量 Linux

    我已经暴露了一个系统环境变量KEY1有价值VALUE1 in etc profile 我知道 我知道 这可能很糟糕 如果我现在在我的壳里 echo KEY1 VALUE1 但当我这样做时 python c import os print o
  • Rails 是否有“未经授权”的例外情况?

    我正在编写一个应用程序 它使用普通的旧 Ruby 对象 PORO 从控制器中抽象出授权逻辑 目前 我有一个名为的自定义异常类NotAuthorized that I rescue from在控制器级别 但我很想知道 Rails 4 是否已经
  • 在 irb 中导航命令行的键盘快捷键

    我看过用户运行 irb 的截屏视频 当他们编写文本时 他们会跳转到行的开头 结尾以及单词的开头 结尾 用于执行此操作的击键是什么 这取决于所使用的外壳吗 Ctrl A gt Move to beginning of line Ctrl E
  • 同一解决方案中的 NuGet 引用

    以前可能已经问过这个问题 如果是 请提供链接 我正在为我的公司开发一套 核心 解决方案 我们在此解决方案集中有几个不同的项目 每个项目在构建时都会变成一个 NuGet 包 以便在我们的其他解决方案项目中使用 我发现我想通过 NuGet 引用
  • Swift Firebase Storage 如何检索名称未知(NSUUID)的图像

    我正在制作一个函数来检索 url 作为用户图像 然而 我的上传图像名称功能是由NSUUID创建的 因此 我不知道每个用户个人资料图片的名称是什么 如何改进我的代码以获得每个用户的用户 imgae 而不是硬编码 img 名称 func get
  • RStudio 通常在空白屏幕中启动;需要 sudo 才能工作

    在新安装的 x64 Ubuntu GNOME 16 04 和 R v3 3 2 上运行的 RStudio v1 0 136 在空白屏幕中启动 终端输出如下 参见屏幕截图 TypeError undefined is not an objec
  • Pydoc 没有看到文档字符串?

    显然我在这里错过了一些严重的事情 这是我的测试程序 Doc and nothing but doc class TestMe object class documentation goes here def testFunc self Fu
  • 应忽略听到“元素‘行为’具有无效子元素”,但因此阻止更新服务引用[重复]

    这个问题在这里已经有答案了 可能的重复 元素 behavior 在 wcf app config 中具有无效的子元素 myFaultExtension https stackoverflow com questions 4677377 th
  • 如何为 Material UI React 添加 RTL 支持

    我正在构建一个 LTR 应用程序 并且想添加 RTL 支持 该应用程序基于 Material UI React 之上 由于我使用的是 CSS Flex Box 因此我能够将应用程序旋转到 RTL 只需将 dir rtl 添加到主体即可 我还