为 MenuProps 和 Parent Select 具有样式组件的组件提供不同的类名称
Give diferent className to MenuProps and Parent Select Componens with styled-components
我正在尝试使用带样式的组件自定义 MUI TextField Select 组件。
想法是样式化的——组件为 Select 字段和菜单提供不同的 classes,因此我可以将它们的样式分开。
const StyledSelect = styled(({ className, ...props }) => {
return (
<TextField {...props}
classes={{ root: className }}
SelectProps={{
MenuProps: {
classes: { paper: className, list: className },
anchorOrigin: {
vertical: "bottom",
horizontal: "left"
},
transformOrigin: {
vertical: "top",
horizontal: "left"
},
getContentAnchorEl: null
},
}}
/>
)
})`
& {
background-color: #454D5D;
border-radius: 10px;
margin-top: 5px;
}
& li {
color: #FFF;
}
&.MuiFormControl-root {
background-color: transparent;
}
& .MuiListItem-root {
font-size: 18px;
}
& .MuiListItem-root.Mui-selected {
background-color: #1A2233;
}
& .MuiFormLabel-root {
font-family: 'Roboto';
font-weight: 300;
}
& .MuiInputLabel-shrink {
color: ${props => props.color};
font-weight: normal;
}
& .MuiInput-underline:after {
border-bottom: 2px solid ${props => props.errors[props.field.name] && props.touched[props.field.name]
? CASABLANCA : props.color};
transition: none;
transform: none;
}
& .MuiInput-underline:before {
border-bottom: 1px solid ${props => props.color}
}
& .MuiSelect-roo {
color: black;
font-family: 'Roboto';
font-weight: 300;
}
& .MuiSelect-select:focus {
background: transparent;
}
`;
我希望我的 TextField class 不同于 MenuProps class
解决此问题的一种方法是为每个需要生成的 class 名称设置一个包装器组件。在我下面的示例中,StyledTextField
负责 TextField
的根 class 名称(className
属性 is equivalent to classes.root),然后是 MenuPaperClass
提供额外的 class 名称。
import React from "react";
import ReactDOM from "react-dom";
import TextField from "@material-ui/core/TextField";
import MenuItem from "@material-ui/core/MenuItem";
import styled from "styled-components";
const StyledTextField = styled(TextField)`
/* && to add specificity */
&& {
border: 1px solid green;
}
`;
const MenuPaperClass = styled(({ className, ...props }) => {
return (
<StyledTextField
SelectProps={{ MenuProps: { classes: { paper: className } } }}
value="1"
select
{...props}
>
<MenuItem value="1">One</MenuItem>
<MenuItem value="2">Two</MenuItem>
<MenuItem value="3">Three</MenuItem>
</StyledTextField>
);
})`
&& {
background-color: lightblue;
}
`;
function App() {
return (
<div className="App">
<MenuPaperClass />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
这不是一个特别优雅的解决方案,如果您要使用 3 个或更多个独立的 classes,它会变得非常乏味,所以我稍后可能会回过头来考虑替代方案 approaches/syntax,但这确实有效。
我正在尝试使用带样式的组件自定义 MUI TextField Select 组件。
想法是样式化的——组件为 Select 字段和菜单提供不同的 classes,因此我可以将它们的样式分开。
const StyledSelect = styled(({ className, ...props }) => {
return (
<TextField {...props}
classes={{ root: className }}
SelectProps={{
MenuProps: {
classes: { paper: className, list: className },
anchorOrigin: {
vertical: "bottom",
horizontal: "left"
},
transformOrigin: {
vertical: "top",
horizontal: "left"
},
getContentAnchorEl: null
},
}}
/>
)
})`
& {
background-color: #454D5D;
border-radius: 10px;
margin-top: 5px;
}
& li {
color: #FFF;
}
&.MuiFormControl-root {
background-color: transparent;
}
& .MuiListItem-root {
font-size: 18px;
}
& .MuiListItem-root.Mui-selected {
background-color: #1A2233;
}
& .MuiFormLabel-root {
font-family: 'Roboto';
font-weight: 300;
}
& .MuiInputLabel-shrink {
color: ${props => props.color};
font-weight: normal;
}
& .MuiInput-underline:after {
border-bottom: 2px solid ${props => props.errors[props.field.name] && props.touched[props.field.name]
? CASABLANCA : props.color};
transition: none;
transform: none;
}
& .MuiInput-underline:before {
border-bottom: 1px solid ${props => props.color}
}
& .MuiSelect-roo {
color: black;
font-family: 'Roboto';
font-weight: 300;
}
& .MuiSelect-select:focus {
background: transparent;
}
`;
我希望我的 TextField class 不同于 MenuProps class
解决此问题的一种方法是为每个需要生成的 class 名称设置一个包装器组件。在我下面的示例中,StyledTextField
负责 TextField
的根 class 名称(className
属性 is equivalent to classes.root),然后是 MenuPaperClass
提供额外的 class 名称。
import React from "react";
import ReactDOM from "react-dom";
import TextField from "@material-ui/core/TextField";
import MenuItem from "@material-ui/core/MenuItem";
import styled from "styled-components";
const StyledTextField = styled(TextField)`
/* && to add specificity */
&& {
border: 1px solid green;
}
`;
const MenuPaperClass = styled(({ className, ...props }) => {
return (
<StyledTextField
SelectProps={{ MenuProps: { classes: { paper: className } } }}
value="1"
select
{...props}
>
<MenuItem value="1">One</MenuItem>
<MenuItem value="2">Two</MenuItem>
<MenuItem value="3">Three</MenuItem>
</StyledTextField>
);
})`
&& {
background-color: lightblue;
}
`;
function App() {
return (
<div className="App">
<MenuPaperClass />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
这不是一个特别优雅的解决方案,如果您要使用 3 个或更多个独立的 classes,它会变得非常乏味,所以我稍后可能会回过头来考虑替代方案 approaches/syntax,但这确实有效。