我需要在出错时将边框颜色的选择组件覆盖为橙色。我的应用程序中的轮廓输入边框颜色在全局范围内提供绿色。仅在出错时必须覆盖边框颜色
import { FormControl, makeStyles, Select, withStyles } from '@material-ui/core';
const useStyles = makeStyles((theme) => ({
select: {
'&:before': {
borderColor: 'red',
},
'&:after': {
borderColor: 'red',
},
},
}));
const CustomSelect = ({
id,
value,
name,
variant,
onChange,
error,
priceType,
}) => {
const classes = useStyles();
return (
<FormControl size='small' error width='154px'>
<Select
id='price-type'
value={priceType}
native
name='priceType'
variant='outlined'
onChange={onChange}
error={true}
inputProps={{
style: {
width: '154px',
},
}}
className={classes.select}
>
<option value={''}></option>
<option value={'Retail'}>Retail</option>
<option value={'X-East'}>X-East</option>
</Select>
</FormControl>
);
};
export default CustomSelect;
答案 0 :(得分:0)
通常在 MaterialUI 中,当我们想要覆盖有条件应用的 MaterialUI 样式时,我们可以使用 classes
属性:
classes={{ root: <class to apply always>, error: <class to apply in error state>}}
您可以在其 API 页面底部阅读有关 CSS API 以及适用于给定组件的类的信息。
或者,我们可以使用更复杂的方法,并在组件处于错误状态时简单地应用规则:
className={ error ? <class to apply in error state> : undefined }
Select
组件的编写时间似乎与大多数其他 MaterialUI 输入组件不同。这是我基于 API 和代码风格的直观印象,但我可能错了。不过,Select
组件根据 Input
属性的值使用 FilledInput
、OutlinedInput
或 variant
之一。由于您使用 outlined
,因此我将在考虑 OutlinedInput
的情况下继续回答此问题。我还将使用绿色作为边框而不是橙色,因为它与红色的区别更加明显。
天真地,我会通过查看 Select
组件的 CSS API 来解决这个问题,然后再仔细查看 OutlinedInput
to which remaining properties of the Select
component are spread。 Select
组件上不存在适用的 CSS API 类来实现您的目标,但 OutlinedInput
有一个 error
类,其描述如下:
Pseudo-class applied to the root element if error={true}.
如果我们检查开发工具中的 OutlinedInput
,我们可以看到带有边框的元素是位于 fieldset
的 root
元素内的 OutlinedInput
(注意:不是 root
的 Select
元素)。如果我们使用 error
类,我们最终会在 root
的 OutlinedInput
元素上应用一个额外的类,这不是我们想要的。尽管如此,我们可以应用一个引用上述子元素的类......这会起作用。
还有一个 css 类 notchedOutline
,我们可以看到它应用于这个 fieldset
导致边框。这里的困境是,如果我们能够向此类添加一些 css,那么它将所有时间应用在 fieldset
上,但我们想应用它仅处于错误状态。
这为我们提供了四种通过 CSS API 影响 css 的可能策略:
root
为目标的基础 OutlinedInput
的 notchedOutline
类。root
状态和子 OutlinedInput
为目标的基础 error
的 notchedOutline
类。error
和目标子级 OutlinedInput
的 notchedOutline
类。notchedOutline
的 OutlinedInput
类。请注意,第二个和第三个更可取,因为它们不需要我们有条件地添加一个类;这是由 MaterialUI 处理的。
在最好的情况下,我希望 Select
组件将其所有不存在的道具转发给它内部使用的元素,在本例中为 OutlinedInput
,但显然,它确实如此不转发它部分支持的元素部分(classes
属性)。这意味着如果我们提供 classes.error
或 classes.notchedOutline
,MaterialUI 将抱怨
Material-UI: The key `XXXX` provided to the classes prop is not implemented in ForwardRef(Select).
而不是将 prop 转发到底层 OutlinedInput
。我不知道这是否是一个错误,但这是目前的工作方式。
这意味着我们不能通过 classes
组件的 Select
属性使用上述四种策略中的任何一种。一种解决方法是使用 Select
className
道具,该道具被转发到 OutlinedInput
,后者又将其转发到 InputBase
,后者将其转发到本机元素,这是相同的作为 root
的 OutlinedInput
元素。因此,如果我们可以访问底层 OutlinedInput
本身,我们可以使用上述所有策略,否则只能使用前两个(然后通过 className
的 Select
属性)。>
如果您希望整个应用程序的错误颜色不是红色,请提供一个主题来更改用于错误的颜色。这是最好的方法,因为它还会更改辅助文本和标签的颜色,否则这些颜色将与 Select
输入的边框颜色不同。
import green from '@material-ui/core/colors/green';
const theme = createTheme({
palette: {
error: {
main: green[500]
},
},
});
这是一种干净且非黑客的方法,也是我推荐的方法。但是,如果您不希望更改错误的一般颜色,这可能不是一个好的解决方案,即使您可以将应用程序的本地部分包装在自己的主题中.
notchedOutline
的类这是一种广泛的解决方法,因为您可以使用上述四种策略以多种不同的方式来解决此问题。所有解决方案的缺点是,它们或多或少有点笨拙,它们只影响 Select
的边框,这意味着当组件处于错误状态时,辅助文本和标签的颜色将与边框不同(您也可以为它们添加样式,使所有这些都非常复杂且难以实现)。
OutlinedInput
我们可以为 OutlinedInput
创建一个具有全局覆盖的主题。由于我们随后操纵了 OutlinedInput
本身,因此我们可以使用上述所有四种策略。
OutlinedInput
的 root
类定位 {{ 1}} 孩子只有当组件处于错误状态时,才必须有条件地应用此主题。这很复杂,不是一个好的选择。
notchedOutline
用于 {{1 }} 类针对 OutlinedInput
状态和 root
子级error
这个效果很好,并且针对 notchedOutline
const themeWithOverrides = createTheme({
overrides: {
MuiOutlinedInput: {
root: {
"&$error": {
"& $notchedOutline": {
border: "1px solid green"
}
}
}
}
}
})
类,其 css 仅在它处于 OutlinedInput
状态时才适用并应用于其 root
子级。选择器是指已经在该组件的主题中默认定义的 css 类。
error
的 notchedOutline
类和 {{ 1}} 孩子OutlinedInput
此解决方案导致 MaterialUI 出现错误消息
error
这反过来又建议我们使用以前针对 notchedOutline
类的解决方案。
const themeWithOverrides = createTheme({
overrides: {
MuiOutlinedInput: {
error: {
"& $notchedOutline": {
border: "1px solid green"
}
}
}
}
})
类的Material-UI: The `MuiOutlinedInput` component increases the CSS specificity of the `error` internal state.
root
这将始终应用我们不想要的样式,因此必须有条件地应用主题,这很麻烦,因此根本不推荐使用此解决方案。
OutlinedInput
组件的 Css 类理论上,我们也可以在这里使用上述所有四种策略。但是,由于我们没有操作 notchedOutline
本身,并且由于 MaterialUI 不会将未为 const themeWithOverrides = createTheme({
overrides: {
MuiOutlinedInput: {
notchedOutline: {
border: "1px solid green"
}
}
}
})
定义的 Select
props 转发到底层组件,因此只剩下两个。< /p>
OutlinedInput
的 classes
属性,该属性应用于面向子 Select
className
Select
组件
OutlinedInput
此解决方案既使用文字 MaterialUI css 类,也要求我们有条件地添加该类。最后,我们必须使用 root
修饰符来覆盖 MaterialUI 默认行为的特异性。总而言之,这有点像黑客的味道。
notchedOutline
的 const useStyles = makeStyles((theme) => ({
errorState: {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid green !important"
}
}
}))
...
<Select
...
className={ errorFlag ? classes.errorState : undefined }
...
</Select>
属性,该属性应用于 !important
className
组件,仅在 {{ 1}} 状态Select
这稍微好一点,因为我们不需要有条件地应用样式。此外,只要在 MaterialUI 默认样式之后注入此样式,我们就可以省略 OutlinedInput
修饰符,因为此规则实现了与 MaterialUI 默认行为相同的特异性。这种方法绝对优于以前的方法。
root
组件的Css类通过{{1} } 支持 notchedOutline
error
组件接受一个属性 const useStyles = makeStyles((theme) => ({
errorState: {
"&.Mui-error": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid green"
}
}
}
}))
...
<Select
...
className={ classes.errorState }
...
</Select>
,它允许您定义要使用的自己的输入组件。在这里,我们可以使用自定义组件,该组件返回带有您想要的修改的 !important
。
OutlinedInput
因为我们在这里可以直接针对 input
工作,所以我们可以使用它的 CSS API,从而使用前面描述的所有四种策略。
请注意,要按照本书进行操作,您还应该将传入的 Select
和 Select
与您默认分配的类合并。
input
道具目标孩子 OutlinedInput
由于我们现在可以访问 export default function CustomInput(props) {
return (
<OutlinedInput
{...props}
<CHANGES HERE>
/>
)
}
属性,因此有条件地提供此类不是一个明智的选择。
OutlinedInput
道具定位状态 {{1} } 和孩子classes.error
同样,由于我们现在可以访问 classes.notchedOutline
属性,因此在此处提供一个针对 classes.root
状态的类而不是直接针对它是一种额外的解决方法,因此不推荐使用。
notchedOutline
道具定位子 classes.error
classes.root
这是一个很好的选择,它允许我们将组件是否处于错误状态的决定留给 MaterialUI。使用字面量 MaterialUI css 类有点麻烦,我们必须提供 error
标志来覆盖 MaterialUI 默认行为的更高特异性。
notchedOutline
道具classes.error
这和上一个一样好。它使我们免于使用文字
MaterialUI css 类,但它迫使我们有条件地添加类。同样在这里,我们必须提供 error
标志以覆盖 MaterialUI 默认行为的更高特异性。
这么简单的事情,好像改起来挺复杂的,真可惜。尽管如此,最好的解决方案似乎是:
如果您想为应用中的所有输入提供与标签和帮助文本一致的统一外观的强大解决方案,请使用全局错误颜色覆盖。
classes.error
如果您希望在所有 notchedOutline
中使用统一的错误颜色,并且如果您对不协调的标签和帮助文本没有意见,请对 const useStyles = makeStyles((theme) => ({
error: {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid green !important"
}
}
}))
export default function CustomInput(props) {
const classes = useStyles()
return (
<OutlinedInput
{...props}
classes={{ ...props.classes, error: classes.error }}
/>
)
}
使用全局覆盖。
!important
如果您需要对单个或几个 classes.notchedOutline
/ const useStyles = makeStyles((theme) => ({
errorOutline: {
border: "1px solid green !important"
}
}))
export default function CustomInput(props) {
const classes = useStyles()
return (
<OutlinedInput
{...props}
classes={{ ...props.classes, notchedOutline: errorFlag ? classes.errorOutline : undefined }}
/>
)
}
进行一次性更改,请使用自定义输入,该输入在组件处于错误状态时有条件地覆盖 !important
如果您可以接受颜色不协调的标签和辅助文本。我更喜欢这个解决方案,因为我不喜欢在我的代码中使用文字 MaterialUI css 类。
import green from '@material-ui/core/colors/green';
const theme = createTheme({
palette: {
error: {
main: green[500]
},
},
})
答案 1 :(得分:0)
您可以使用这种样式
const useStyles = makeStyles((theme) => ({
select: {
borderColor:'#f00',
'&:focus': {
borderColor: '#f00',
},
},
}));