Насколько надежны имена глобальных классов MUI в JSS?

У меня такой код:

const formControlStyles = {
  root: {
    '&:hover .MuiFormLabel-root': {

     }
  }
}

Безопасно ли использовать имя класса в переопределениях темы для доступа к другим компонентам? Кроме того, существует ли способ вложения стилей из других компонентов с помощью JSS?


person Gasim    schedule 17.03.2020    source источник


Ответы (1)


Это довольно безопасно, но с одной оговоркой. Если вы используете вложенные темы, имена глобальных классов, применяемые во вложенной теме, будут иметь непредсказуемый суффикс (например, MuiFormLabel-root-371). Этот суффикс необходим, потому что стили по умолчанию, связанные с вложенной темой, могут быть разными.

Чтобы полностью безопасно настроить таргетинг на имена классов, вы можете использовать *= селектор атрибутов (например, [class*="MuiFormLabel-root"]), который проверяет, имеет ли элемент имя класса, которое содержит MuiFormLabel-root, вместо того, чтобы точно соответствовать ему. Вы можете увидеть этот подход, используемый в самом Material-UI здесь.

Пока вы не собираетесь использовать вложенные темы, безопасно (и гораздо более читабельно) использовать более простой синтаксис точного сопоставления имен глобальных классов. Альтернативный подход - указать класс JSS для вложенного компонента и обратиться к этому классу с использованием синтаксиса JSS для ссылка на другое правило в той же таблице стилей (например, $myFormLabel в моем примере), но для этого требуется возможность применить этот класс (например, classes.myFormLabel в моем примере) к вложенному компоненту.

Ниже приведен пример, демонстрирующий проблему (и некоторые возможные решения) при использовании вложенных тем.

import React from "react";
import {
  ThemeProvider,
  createMuiTheme,
  makeStyles
} from "@material-ui/core/styles";
import FormLabel from "@material-ui/core/FormLabel";

const theme1 = createMuiTheme();
const theme2 = createMuiTheme({
  overrides: {
    MuiFormLabel: {
      root: {
        color: "#00ff00"
      }
    }
  }
});

const useStyles = makeStyles({
  mostlySafe: {
    "&:hover .MuiFormLabel-root": {
      color: "red"
    }
  },
  safeButTediousAndMoreErrorProneSyntax: {
    '&:hover [class*="MuiFormLabel-root"]': {
      color: "purple"
    }
  },
  alternativeApproach: {
    "&:hover $myFormLabel": {
      color: "blue"
    }
  },
  myFormLabel: {}
});
export default function App() {
  const classes = useStyles();
  return (
    <ThemeProvider theme={theme1}>
      <div>
        <div className={classes.mostlySafe}>
          <FormLabel>FormLabel within top-level theme</FormLabel>
        </div>
        <ThemeProvider theme={theme2}>
          <div className={classes.mostlySafe}>
            <FormLabel>
              FormLabel within nested theme (hover styling doesn't work)
            </FormLabel>
          </div>
          <div className={classes.safeButTediousAndMoreErrorProneSyntax}>
            <FormLabel>
              FormLabel within nested theme using safe approach
            </FormLabel>
          </div>
          <div className={classes.alternativeApproach}>
            <FormLabel className={classes.myFormLabel}>
              FormLabel within nested theme without using global class names
            </FormLabel>
          </div>
        </ThemeProvider>
      </div>
    </ThemeProvider>
  );
}

 Редактировать глобальные имена классов

person Ryan Cogswell    schedule 17.03.2020
comment
Спасибо вам за помощь! Один вопрос, который остался у меня после вашего ответа (в частности, реализация компонента MUI AutoComplete). Что произойдет, если для disableGlobal установлено значение true? Будет ли сломан компонент автозаполнения? Стили будут недоступны? - person Gasim; 17.03.2020
comment
@Gasim Это интересный момент. Да, если disableGlobal установлен в true, это нарушит стиль Autocomplete. В v5 планируется заменить JSS на styled-components в качестве внутреннего решения для стилизации. Я еще не знаю, каковы будут все последствия этого, но я подозреваю, что MUI станет более зависимым от глобальных имен классов, а не меньше. Подозреваю, что вариант disableGlobal полностью исчезнет. - person Ryan Cogswell; 17.03.2020
comment
@Gasim FYI - вот ссылка на код, где disableGlobal вступает в игру: github.com/mui-org/material-ui/blob/v4.9.5/packages/. - person Ryan Cogswell; 17.03.2020