Skip to content
56 changes: 48 additions & 8 deletions packages/accordion/src/lib/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const meta: Meta<typeof Accordion> = {
tags: ['autodocs'],
argTypes: {
variant: {
options: ['filled', 'outlined'],
options: ['filled', 'outlined', 'flush'],
},
},
};
Expand Down Expand Up @@ -85,6 +85,28 @@ export const _Variants: StoryObj<typeof Accordion> = {
</AccordionDetails>
</Accordion>
</Grid>
<Grid size={{ xs: 12 }}>
<Accordion {...args} variant='flush'>
<AccordionSummary aria-controls="flush-summary-content" id="flush-summary-header" secondary="Secondary">
Flush
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit
leo lobortis eget.
<Box sx={{ mt: 2 }}>
<Accordion {...args} variant='flush'>
<AccordionSummary aria-controls="flush-nested-content" id="flush-nested-header">
Flush Nested Accordion
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet
blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
</Box>
</AccordionDetails>
</Accordion>
</Grid>
</Grid>
),
};
Expand All @@ -97,13 +119,13 @@ export const _Variants: StoryObj<typeof Accordion> = {
* this is due to Material's default gutter behavior when expanded along with how they overwrite the behavior when disabling the gutters.
*/
export const _Spacing: StoryObj<typeof Accordion> = {
render: () => (
render: (args: AccordionProps) => (
<div>
<Typography variant="h5" component="h2">
Grouped
</Typography>
<div>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="grouped-panel1-content" id="grouped-panel1-header">
Accordion 1
</AccordionSummary>
Expand All @@ -112,7 +134,7 @@ export const _Spacing: StoryObj<typeof Accordion> = {
leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="grouped-panel2-content" id="grouped-panel2-header">
Accordion 2
</AccordionSummary>
Expand All @@ -121,7 +143,7 @@ export const _Spacing: StoryObj<typeof Accordion> = {
leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="grouped-panel3-content" id="grouped-panel3-header">
Accordion 3 with Actions
</AccordionSummary>
Expand All @@ -140,7 +162,7 @@ export const _Spacing: StoryObj<typeof Accordion> = {
Separated in a Grid
</Typography>
<Grid size={{ xs: 12 }}>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="panel1-content" id="panel1-header">
Accordion 4
</AccordionSummary>
Expand All @@ -151,7 +173,7 @@ export const _Spacing: StoryObj<typeof Accordion> = {
</Accordion>
</Grid>
<Grid size={{ xs: 12 }}>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="panel2-content" id="panel2-header">
Accordion 5
</AccordionSummary>
Expand All @@ -162,7 +184,7 @@ export const _Spacing: StoryObj<typeof Accordion> = {
</Accordion>
</Grid>
<Grid size={{ xs: 12 }}>
<Accordion>
<Accordion {...args}>
<AccordionSummary aria-controls="panel3-content" id="panel3-header">
Accordion 6 with Actions
</AccordionSummary>
Expand Down Expand Up @@ -220,6 +242,24 @@ export const _States: StoryObj<typeof Accordion> = {
</AccordionDetails>
</Accordion>
</Grid>
<Grid size={{ xs: 12 }}>
<Accordion {...args} variant="flush" defaultExpanded>
<AccordionSummary aria-controls="flushexpanded-content" id="flushexpanded-header">
Flush Expanded
</AccordionSummary>
<AccordionDetails>
<Accordion>
<AccordionSummary aria-controls="flushexpanded-nested-content" id="flushexpanded-nested-header">
Flush Nested Accordion
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet
blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
</AccordionDetails>
</Accordion>
</Grid>
<Grid size={{ xs: 12 }}>
<Accordion {...args}>
<AccordionSummary aria-controls="focused-content" id="focused-header" className="Mui-focusVisible">
Expand Down
53 changes: 43 additions & 10 deletions packages/accordion/src/lib/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import MuiAccordion, { AccordionProps as MuiAccordionProps } from '@mui/material
import { styled } from '@mui/material/styles';
import { forwardRef } from 'react';

type Variant = 'filled' | 'outlined' | 'flush';

export type AccordionProps = {
/** @default "filled" */
variant?: 'filled' | 'outlined';
variant?: Variant
/**
* Disable nested styling for child `Accordions`
* @default false
Expand Down Expand Up @@ -33,19 +35,50 @@ const OutlinedAccordion = styled(MuiAccordion, {
backgroundColor: theme.palette.background.paper,
},
'> .MuiCollapse-root > .MuiCollapse-wrapper > .MuiCollapse-wrapperInner > .MuiAccordion-region > .MuiAccordionDetails-root:first-of-type':
{
borderTop: `1px solid ${theme.palette.divider}`,
},
{
borderTop: `1px solid ${theme.palette.divider}`,
},
}));

const FlushAccordion = styled(MuiAccordion, {
name: 'MuiAccordion',
slot: 'AvFlush',
overridesResolver: (props, styles) => styles.avFlush,
})(({ theme }) => ({
border: 0,
borderBottom: `1px solid ${theme.palette.divider}`,
'&&': {
borderRadius: 0,
},
'&:first-of-type': {
borderTop: `1px solid ${theme.palette.divider}`,
},
'> .MuiAccordion-heading .MuiAccordionSummary-root:not(.Mui-focusVisible, :hover, :active)': {
backgroundColor: 'transparent'
},
'> .MuiAccordion-heading .MuiAccordionSummary-root': {
padding: 8,
minHeight: 40,
},
'> .MuiAccordion-heading .MuiAccordionSummary-root .MuiAccordionSummary-content': {
margin: 0
},
'& .MuiAccordionDetails-root .MuiAccordion-heading': {
borderRadius: 4,
}
}));

const VariantComponent: Record<Variant, typeof FilledAccordion> = {
filled: FilledAccordion,
outlined: OutlinedAccordion,
flush: FlushAccordion
}

export const Accordion = forwardRef<HTMLDivElement, AccordionProps>((allProps, ref) => {
const { variant = 'filled', disableNestedStyling = false, className, ...props } = allProps;
const Variant = VariantComponent[variant]

const classnames = `${variant === 'filled' ? 'MuiAccordion-avFilled' : 'MuiAccordion-avOutlined'}${disableNestedStyling ? ' Av-disableNested' : ''} ${className || ''}`;
const classnames = `MuiAccordion-av${variant.charAt(0).toUpperCase() + variant.slice(1)}${disableNestedStyling ? ' Av-disableNested' : ''} ${className || ''}`;

return variant === 'filled' ? (
<FilledAccordion className={classnames} {...props} ref={ref} />
) : (
<OutlinedAccordion className={classnames} {...props} ref={ref} />
);
return <Variant className={classnames} {...props} ref={ref} />;
});