How to Override Expansionpanelsummary Deep Elements with Styled-Components

How can I override ExpansionPanelSummary deep elements with styled-components?

This difficulty is independent of using styled-components and just has to do with wrapping ExpansionPanelSummary in another component.

You can similarly reproduce this with the following wrapping of ExpansionPanelSummary:

const MyCustomSummary = props => {
return (
<ExpansionPanelSummary {...props} expandIcon={<ExpandMoreIcon />}>
<Typography>{props.text}</Typography>
</ExpansionPanelSummary>
);
};

There are several component groups like this where a Material-UI parent component looks for a particular type of child component and treats that child specially. For instance, you can find the following block in ExpansionPanel

      if (isMuiElement(child, ['ExpansionPanelSummary'])) {
summary = React.cloneElement(child, {
disabled,
expanded,
onChange: this.handleChange,
});
return null;
}

Fortunately, Material-UI has a straightforward way to tell it that your custom component should be treated the same as a particular Material-UI component via the muiName property:

MyCustomSummary.muiName = "ExpansionPanelSummary";

or in your case it would look like:

export const ExpansionPanelSummary = styled(props => (
<MUIExpansionPanelSummary
{...props}
/>
))``;

ExpansionPanelSummary.muiName = "ExpansionPanelSummary";

Edit Custom ExpansionPanelSummary

Custom component within ExpansionPanel fails to render

This problem has the same cause and solution as the question I answered here:

How can I override ExpansionPanelSummary deep elements with styled-components?

You need the following to fix it:

function ClusterSummary(props) {
return (
<ExpansionPanelSummary>
<Typography>{props.cluster.title}</Typography>
</ExpansionPanelSummary>
);
}
// This is what needs to be added
ClusterSummary.muiName = "ExpansionPanelSummary";

See my previous answer for details about why this is needed.

MaterialUI for React with Styled-Components

There are a several ways to approach this. One approach is to use child selectors (as mentioned in Kaca992's answer), but the Paper is not a direct child of the Dialog so to use this approach you need & > .MuiDialog-container > .MuiPaper-root. Another option is to use Dialog's PaperComponent prop and provide it with a styled Paper component. A third option is to leverage the MuiDialog-paper CSS class.

All three approaches are shown in the example below.

import React from "react";
import Button from "@material-ui/core/Button";
import DialogTitle from "@material-ui/core/DialogTitle";
import Dialog from "@material-ui/core/Dialog";
import Paper from "@material-ui/core/Paper";
import styled from "styled-components";

const StyledDialog = styled(Dialog)`
& > .MuiDialog-container > .MuiPaper-root {
background-color: purple;
}
`;
const StyledDialog2 = styled(Dialog)`
& .MuiDialog-paper {
background-color: blue;
}
`;
const StyledPaper = styled(Paper)`
background-color: green;
`;

export default function SimpleDialogDemo() {
const [open1, setOpen1] = React.useState(false);
const [open2, setOpen2] = React.useState(false);
const [open3, setOpen3] = React.useState(false);

return (
<div>
<Button variant="outlined" color="primary" onClick={() => setOpen1(true)}>
Open dialog using child selectors
</Button>
<Button variant="outlined" color="primary" onClick={() => setOpen3(true)}>
Open dialog using MuiDialog-paper
</Button>
<Button variant="outlined" color="primary" onClick={() => setOpen2(true)}>
Open dialog using custom Paper
</Button>
<StyledDialog
onClose={() => setOpen1(false)}
aria-labelledby="simple-dialog-title"
open={open1}
>
<DialogTitle id="simple-dialog-title">
Paper styled via child selectors
</DialogTitle>
</StyledDialog>
<StyledDialog2
onClose={() => setOpen3(false)}
aria-labelledby="simple-dialog-title"
open={open3}
>
<DialogTitle id="simple-dialog-title">
Paper styled via MuiDialog-paper
</DialogTitle>
</StyledDialog2>
<Dialog
onClose={() => setOpen2(false)}
aria-labelledby="simple-dialog-title"
open={open2}
PaperComponent={StyledPaper}
>
<DialogTitle id="simple-dialog-title">
Paper styled via custom Paper component
</DialogTitle>
</Dialog>
</div>
);
}

Edit Dialog Paper

Can't override a style of a deeply nested component (Material-UI Jss Styling)

The &$ syntax references a rule in the same style sheet, you need to create an expanded rule and pass it into the classes object e.g.

const styles = theme => ({
expandIcon: {
"&$expanded": {
transform: "translateY(-50%) rotate(90deg)"
}
},
expanded: {},
});

<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
classes={{
expandIcon: classes.expandIcon,
expanded: classes.expanded,
}}
>

Codesandbox example: https://codesandbox.io/s/x256q3xz44

Find two consecutive rows

Assuming the rows have sequential IDs, something like this may be what you're looking for:

select top 1 * 
from
Bills b1
inner join Bills b2 on b1.id = b2.id - 1
where
b1.IsEstimate = 1 and b2.IsEstimate = 1
order by
b1.BillDate desc


Related Topics



Leave a reply



Submit