CSS 将类型作为特异性选择器所必需的空定义(material UI 在 React 中)
CSS empty definition necessary to have the type as specificity selector (material UI in React)
未选中的切换按钮的样式效果很好。
但是当你没有定义一个空的class选择器时,选择的切换按钮的样式不会出现:
./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);
这个可能跟道具中的类型定义有关。当您从 styles 定义中删除选择器 'selected' 时,它在接口 IAppProps 中不再可用。
如何在接口中定义这种类型?
工作示例:https://codesandbox.io/s/elated-sammet-y7wh7?fontsize=14
更新 1:还尝试了 增加道具,如所述in the material-ui docs:
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);
我相信你只是对JSS的工作原理和一些语法的含义有误解。相关文档是here.
当您定义样式对象(或接受主题并返回对象的函数)时,该对象中的每个键都被 JSS 称为 "rule"。键是规则名称,JSS 会将值转换为 CSS class。您从 useStyles
返回的 classes
对象或在使用 withStyles
时作为道具注入的对象然后将规则名称映射到生成的 CSS class 名称.
$ruleName
语法是一种引用样式对象中其他规则的 CSS class 名称的方法。 &
指的是父规则。在您的示例中,您有名为 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}
除了为默认样式应用的 class 名称之外,您还告诉它应用 "root-0 selected-0" 作为 class 名称。如果没有空的 selected: {}
规则名称,您就无法从 root
规则中引用 $selected
(如果这样做,JSS 应该会在控制台中给您一个警告)。
有一个稍微简单的替代方法(从 v4 开始)用于引用 selected
class 名称。 selected
是 Material-UI 特殊状态之一,它被称为 pseudo-classes 并且文档为每个状态提供了默认的 class 名称(例如 Mui-selected
)。
这意味着您可以执行以下操作:
root: {
backgroundColor: "blue",
"&.Mui-selected": {
color: "blue",
backgroundColor: "red"
}
}
这不再引用另一条规则,因此不需要 selected: {}
,classes
属性中也不需要 selected: classes.selected
。相反,这是引用 Material-UI 在 selected={true}
.
时应用于默认样式的实际 class 名称
未选中的切换按钮的样式效果很好。
但是当你没有定义一个空的class选择器时,选择的切换按钮的样式不会出现:
./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);
这个可能跟道具中的类型定义有关。当您从 styles 定义中删除选择器 'selected' 时,它在接口 IAppProps 中不再可用。
如何在接口中定义这种类型?
工作示例:https://codesandbox.io/s/elated-sammet-y7wh7?fontsize=14
更新 1:还尝试了 增加道具,如所述in the material-ui docs:
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);
我相信你只是对JSS的工作原理和一些语法的含义有误解。相关文档是here.
当您定义样式对象(或接受主题并返回对象的函数)时,该对象中的每个键都被 JSS 称为 "rule"。键是规则名称,JSS 会将值转换为 CSS class。您从 useStyles
返回的 classes
对象或在使用 withStyles
时作为道具注入的对象然后将规则名称映射到生成的 CSS class 名称.
$ruleName
语法是一种引用样式对象中其他规则的 CSS class 名称的方法。 &
指的是父规则。在您的示例中,您有名为 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}
除了为默认样式应用的 class 名称之外,您还告诉它应用 "root-0 selected-0" 作为 class 名称。如果没有空的 selected: {}
规则名称,您就无法从 root
规则中引用 $selected
(如果这样做,JSS 应该会在控制台中给您一个警告)。
有一个稍微简单的替代方法(从 v4 开始)用于引用 selected
class 名称。 selected
是 Material-UI 特殊状态之一,它被称为 pseudo-classes 并且文档为每个状态提供了默认的 class 名称(例如 Mui-selected
)。
这意味着您可以执行以下操作:
root: {
backgroundColor: "blue",
"&.Mui-selected": {
color: "blue",
backgroundColor: "red"
}
}
这不再引用另一条规则,因此不需要 selected: {}
,classes
属性中也不需要 selected: classes.selected
。相反,这是引用 Material-UI 在 selected={true}
.