|
| 1 | +import { ExpandMore } from "@mui/icons-material"; |
| 2 | +import { |
| 3 | + Accordion, |
| 4 | + AccordionActions, |
| 5 | + AccordionDetails, |
| 6 | + AccordionSummary, |
| 7 | + PaletteColor, |
| 8 | + styled, |
| 9 | + SxProps, |
| 10 | + Typography, |
| 11 | + useTheme, |
| 12 | +} from "@mui/material"; |
| 13 | +import * as React from "react"; |
| 14 | + |
| 15 | +type StyledDetailsProps = React.PropsWithChildren<{ |
| 16 | + expandIcon?: React.ReactNode; |
| 17 | + open?: boolean; |
| 18 | + summary?: React.ReactNode; |
| 19 | + actions?: React.ReactNode; |
| 20 | +}>; |
| 21 | + |
| 22 | +type BaseStyledDetailsProps = StyledDetailsProps & { |
| 23 | + paletteColor: PaletteColor; |
| 24 | + transparencyOnExpand?: number; |
| 25 | +}; |
| 26 | + |
| 27 | +const BaseStyledDetails: React.FC<BaseStyledDetailsProps> = ({ |
| 28 | + expandIcon, |
| 29 | + open, |
| 30 | + summary, |
| 31 | + children, |
| 32 | + actions, |
| 33 | + paletteColor, |
| 34 | + transparencyOnExpand, |
| 35 | +}) => { |
| 36 | + const StyledAccordion = styled(Accordion)(({ theme }) => ({ |
| 37 | + width: "100%", |
| 38 | + paddingRight: theme.spacing(1), |
| 39 | + paddingLeft: theme.spacing(1), |
| 40 | + border: `1px solid ${paletteColor.dark}`, |
| 41 | + borderRadius: "0.5rem", |
| 42 | + fontWeight: 500, |
| 43 | + })); |
| 44 | + |
| 45 | + const StyledAccordionSummary = styled(AccordionSummary)(() => ({ |
| 46 | + color: paletteColor.dark, |
| 47 | + })); |
| 48 | + |
| 49 | + const rootSx: SxProps = { |
| 50 | + transition: "background-color 0.3s ease", |
| 51 | + "&.Mui-expanded": { |
| 52 | + backgroundColor: `color-mix(in srgb, ${paletteColor.light} ${transparencyOnExpand || 10}%, transparent)`, |
| 53 | + }, |
| 54 | + }; |
| 55 | + |
| 56 | + const DefaultExpandIcon = styled(ExpandMore)(({ theme }) => ({ |
| 57 | + color: paletteColor.dark, |
| 58 | + fontSize: theme.typography.h4.fontSize, |
| 59 | + })); |
| 60 | + |
| 61 | + return ( |
| 62 | + <StyledAccordion expanded={open} disableGutters square elevation={0} slotProps={{ root: { sx: rootSx } }}> |
| 63 | + {summary && ( |
| 64 | + <StyledAccordionSummary expandIcon={expandIcon || <DefaultExpandIcon />}> |
| 65 | + {typeof summary === "string" ? <Typography variant="h5">{summary}</Typography> : summary} |
| 66 | + </StyledAccordionSummary> |
| 67 | + )} |
| 68 | + <AccordionDetails sx={{ pt: "0", pb: "1rem", px: "2rem" }}>{children}</AccordionDetails> |
| 69 | + {actions && <AccordionActions sx={{ pt: "0", pb: "1rem", px: "2rem" }}>{actions}</AccordionActions>} |
| 70 | + </StyledAccordion> |
| 71 | + ); |
| 72 | +}; |
| 73 | + |
| 74 | +export const PrimaryStyledDetails: React.FC<StyledDetailsProps> = (props) => { |
| 75 | + const { palette } = useTheme(); |
| 76 | + return <BaseStyledDetails {...props} paletteColor={palette.primary} transparencyOnExpand={20} />; |
| 77 | +}; |
| 78 | + |
| 79 | +export const HighlightedStyledDetails: React.FC<StyledDetailsProps> = (props) => { |
| 80 | + const { palette } = useTheme(); |
| 81 | + return <BaseStyledDetails {...props} paletteColor={palette.highlight} transparencyOnExpand={10} />; |
| 82 | +}; |
0 commit comments