英文:
How to target the mui paper component from select style without using the sx props?
问题
I am trying to style the Select MUI component using the styled function. Since I want to share this style later on, I don't want to keep using sx. I've tried a couple of approaches, but I am missing the right class to be able to target the Paper directly from within the styled function.
// Styled
export const StyledSelect = styled(Select)<SelectProps>(({ theme }) => ({
textAlign: 'start',
margin: '5px',
fontWeight: 800,
'& .MuiSelect-select': {
// List
'& .MuiList-root': {
color: 'green',
backgroundColor: 'red',
},
// Paper
'& .MuiMenu-paper': {
backgroundColor: 'red',
},
},
}))
// Component
<FormControl>
<StyledSelect
variant={variant}
labelId='select-label'
name={name}
disabled={disabled}
value={value}
onChange={onChangeFn}
displayEmpty
>
</StyledSelect>
</FormControl>
请注意,上述代码是对你提供的代码片段的翻译,不包含其他额外信息。
英文:
I am trying to style the Select MUI component using the styled function. Since I want to share this style later on, I don't want to keep using sx. I've tried a couple of approaches, but I am missing the right class to be able to target the Paper directly from within the styled function
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
// Styled
export const StyledSelect = styled(Select)<SelectProps>(({ theme }) => ({
textAlign: 'start',
margin: '5px',
fontWeight: 800,
'& .MuiSelect-select': {
// List
'& .MuiList-root': {
color: 'green',
backgroundColor: 'red',
},
// Paper
'& .MuiMenu-paper': {
backgroundColor: 'red',
},
},
})
// Component
<FormControl>
<StyledSelect
variant={variant}
labelId='select-label'
// This works 100%
// MenuProps={{
// PaperProps: {
// sx: {
// backgroundColor: 'transparent',
// backdropFilter: 'blur(10px)',
// },
// },
// }}
name={name}
disabled={disabled}
value={value}
onChange={onChangeFn}
displayEmpty
>
</StyledSelect>
</FormControl>
<!-- end snippet -->
答案1
得分: 1
The MUI Paper
在默认的 Select
内部一直是一个比较棘手的部分,因为 Paper
被作为一个样式化组件来处理,因为它在 Select
的DOM层次结构之外(因为它使用了 Portal)。为了对其进行样式化(以及 Select
),你首先需要对 Select
进行样式化,然后使用样式化的 Select
作为基本组件,用来对 Paper
进行样式化。例如:
const BaseSelect = styled(Select)(({ theme }) => ({
backgroundColor: "green", // 仅用于示例
textAlign: 'start',
margin: '5px',
fontWeight: 800,
}));
// 对 Menu Paper 进行样式化
const StyledSelect = styled(({ className, ...props }: SelectProps) => (
<BaseSelect {...props} MenuProps={{ PaperProps: { className } }} />
))(({ theme }) => ({
backgroundColor: "red", // 仅用于示例
// backgroundColor: "transparent",
backdropFilter: "blur(10px)"
}));
...
// 正常使用
// <StyledSelect ... >
工作中的 CodeSandbox: https://codesandbox.io/s/styled-mui-select-and-paper-2dmpct?file=/demo.tsx
英文:
The MUI Paper
within a default Select
has always been a trickier to handle as a styled component because the Paper
falls outside of the Select
's DOM hierarchy (due to it use of a Portal). In order to style it (and the Select
), you first need to style the Select
and then use that styled Select
as the base component from which to style the Paper
. For example:
const BaseSelect = styled(Select)(({ theme }) => ({
backgroundColor: "green", // Added just for the example
textAlign: 'start',
margin: '5px',
fontWeight: 800,
}));
// To style the Menu Paper
const StyledSelect = styled(({ className, ...props }: SelectProps) => (
<BaseSelect {...props} MenuProps={{ PaperProps: { className } }} />
))(({ theme }) => ({
backgroundColor: "red", // Added just for the example
// backgroundColor: "transparent",
backdropFilter: "blur(10px)"
}));
...
// Use as you normally would
// <StyledSelect ... >
Working CodeSandbox: https://codesandbox.io/s/styled-mui-select-and-paper-2dmpct?file=/demo.tsx
答案2
得分: 1
1️⃣ 使用 sx
属性创建基础组件:
export const BaseSelect = (props: SelectProps) => {
return (
<Select
{...props}
sx={{
bgcolor: 'green',
...props.sx, // 从 props 中扩展 sx,以便在需要时覆盖这些样式
}}
MenuProps={{
PaperProps: {
sx: {
bgcolor: 'red', // Paper 的 sx 样式
},
},
}}
/>
)}
// 用法
<BaseSelect
value={age}
label="Age"
sx={{
height: 100, // 仍然可以使用 sx 并在需要时覆盖基础样式
}}
>
2️⃣ 创建可重用的 sx
变量:
export const SELECT_BASE_SX: SxProps = {
bgcolor: 'green',
}
export const PAPER_SX: SxProps = {
bgcolor: 'red',
}
// 用法
<Select
sx={{
...SELECT_BASE_SX,
height: 100,
}}
MenuProps={{
PaperProps: {
sx: {
...PAPER_SX,
},
},
}}
/>
希望这有所帮助。
英文:
We have faced similar issues while using styled-components
to target child classes to create a base component. Sometimes there are multiple child components you want to target. It's a bit tricky. You will face similar issues with components like Autocomplete
, DatePicker
, etc.
So we start using two different approaches.
✅1️⃣ Create a base component using sx
props:
export const BaseSelect = (props: SelectProps) => {
return (
<Select
{...props}
sx={{
bgcolor: 'green',
...props.sx, //spread your sx from props, so you can override these styles if needed
}}
MenuProps={{
PaperProps: {
sx: {
bgcolor: 'red', //sx for Paper
},
},
}}
/>
)}
//USAGE
<BaseSelect
value={age}
label="Age"
sx={{
height: 100, //You can still use sx and override base styling if needed
}}
>
<br/>
✅2️⃣ Create reusable sx
variables:
export const SELECT_BASE_SX: SxProps = {
bgcolor: 'green',
}
export const PAPER_SX: SxProps = {
bgcolor: 'red',
}
//USAGE
<Select
sx={{
...SELECT_BASE_SX,
height: 100,
}}
MenuProps={{
PaperProps: {
sx: {
...PAPER_SX,
},
},
}}
/>
I hope it helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论