Пустое определение CSS необходимо, чтобы тип был выбран как специфичность (пользовательский интерфейс материала в React) - PullRequest
1 голос
/ 11 июля 2019

Стиль для невыбранной кнопки переключения работает хорошо.

Но стиль выбранной кнопки-переключателя не отображается, если вы не определили пустой селектор классов:

. / App.js

import * as React from "react";
import { render } from "react-dom";

import { createStyles, WithStyles } from "@material-ui/core";
import { ToggleButtonGroup, ToggleButton } from "@material-ui/lab";
import { withStyles } from "@material-ui/core/styles";

const styles = () =>
  createStyles({
    root: {
      backgroundColor: "blue",
      "&$selected": {
        color: "blue",
        backgroundColor: "yellow"
      }
    },
    // this empty definition needs to be here otherwise it won't work
    selected: {}
  });

export interface IAppProps extends WithStyles<typeof styles> {}

const App: React.FC<IAppProps> = ({ classes }: IAppProps) => {
  return (
        <ToggleButton
          classes={{
            root: classes.root,
            selected: classes.selected
          }}
          selected={true}
        >
          option 1
        </ToggleButton>
  );
};

const AppWithStyles = withStyles(styles)(App);
const rootElement = document.getElementById("root");
render(<AppWithStyles />, rootElement);

Этот возможно как-то связан с определением типа в подпорках. Когда вы удаляете селектор 'selected' из определения styles , он больше не доступен в интерфейсе IAppProps.

Как вы можете определить этот тип в интерфейсе?

Рабочий пример: https://codesandbox.io/s/elated-sammet-y7wh7?fontsize=14


обновление 1: также пробовал Дополнение реквизита , как описано в документации по материалам :

const styles = () =>
  createStyles({
    toggleButton: {
      backgroundColor: "blue",
      "&$toggleButtonSelected": {
        color: "blue",
        backgroundColor: "yellow"
      }
    },
  });

export interface IAppProps {
  classes: {
    toggleButton: string;
    toggleButtonSelected: string;
  };
}

const App: React.FC<IAppProps> = ({ classes }: IAppProps) => {
// ...

Без удачи.


обновление 2: использование ловушки делает приведение типов лишним, но это также не исправит это:

import * as React from "react";
import { render } from "react-dom";

import { createStyles, makeStyles } from "@material-ui/core";
import { ToggleButtonGroup, ToggleButton } from "@material-ui/lab";

const useStyles = makeStyles(() =>
    createStyles({
      root: {
        backgroundColor: "blue",
        "&$selected": {
          color: "blue",
          backgroundColor: "red"
        }
      },
      // this still needs to be there...
      // selected: {}
    })
  )

export interface IAppProps {}

const App: React.FC<IAppProps> = () => {

  const classes = useStyles();

  return ( 
    // ...
  )
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

1 Ответ

1 голос
/ 11 июля 2019

Полагаю, у вас просто неправильное понимание того, как работает JSS, и значения некоторых синтаксисов.Соответствующая документация: здесь .

Когда вы определяете свой объект стилей (или функцию, берущую в теме и возвращающую объект), каждый ключ в этом объекте упоминается JSS как "править».Ключом является имя правила, и JSS преобразует значение в класс CSS.Объект classes, который вы возвращаете из useStyles или который вводится как реквизит при использовании withStyles, затем отображает имена правил в сгенерированные имена классов CSS.

Синтаксис $ruleName являетсяспособ ссылки на имя класса CSS одного из других правил в вашем объекте стилей.& относится к родительскому правилу.В вашем примере у вас есть правила с именами root и selected (когда они не закомментированы).

Следующее:

root: {
        backgroundColor: "blue",
        "&$selected": {
          color: "blue",
          backgroundColor: "red"
        }
      },
selected: {}

будет компилироваться в CSS следующим образом:

.root-0 {
   background-color: blue;
}
.root-0.selected-0 {
   color: blue;
   background-color: red;
}

Передавая Material-UI следующее:

          classes={{
            root: classes.root,
            selected: classes.selected
          }}
          selected={true}

Вы говорите ему применять "root-0 selected-0" в качестве имен классов в дополнение к именам классовприменяется для стиля по умолчанию.Без пустого имени правила selected: {} вы не можете ссылаться на $selected из правила root (если вы это сделаете, JSS должен показывать вам предупреждение в консоли).

более простая альтернатива (начиная с v4) для ссылки на имя класса selected.selected - это одно из специальных состояний Material-UI, которое оно называет псевдоклассами , и документация предоставляет имя класса по умолчанию для каждого (например, Mui-selected).

Thisозначает, что вы можете сделать следующее:

root: {
        backgroundColor: "blue",
        "&.Mui-selected": {
          color: "blue",
          backgroundColor: "red"
        }
      }

Это больше не ссылается на другое правило, поэтому selected: {} не требуется, и selected: classes.selected не требуется в classes проп.Вместо этого это ссылка на фактическое имя класса, которое Material-UI применяет для стиля по умолчанию, когда selected={true}.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...