Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Accordion] Migrate AccordionSummary to emotion #24540

Merged
merged 6 commits into from
Jan 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/pages/api-docs/accordion-summary.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" } },
"expandIcon": { "type": { "name": "node" } },
"focusVisibleClassName": { "type": { "name": "string" } }
"focusVisibleClassName": { "type": { "name": "string" } },
"sx": { "type": { "name": "object" } }
},
"name": "AccordionSummary",
"styles": {
Expand All @@ -20,6 +21,6 @@
"filename": "/packages/material-ui/src/AccordionSummary/AccordionSummary.js",
"inheritance": { "component": "ButtonBase", "pathname": "/api/button-base/" },
"demos": "<ul><li><a href=\"/components/accordion/\">Accordion</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"children": "The content of the component.",
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"expandIcon": "The icon to display as the expand indicator.",
"focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It&#39;s a polyfill for the <a href=\"https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo\">CSS :focus-visible selector</a>. The rationale for using this feature <a href=\"https://github.com/WICG/focus-visible/blob/master/explainer.md\">is explained here</a>. A <a href=\"https://github.com/WICG/focus-visible\">polyfill can be used</a> to apply a <code>focus-visible</code> class to other components if needed."
"focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It&#39;s a polyfill for the <a href=\"https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo\">CSS :focus-visible selector</a>. The rationale for using this feature <a href=\"https://github.com/WICG/focus-visible/blob/master/explainer.md\">is explained here</a>. A <a href=\"https://github.com/WICG/focus-visible\">polyfill can be used</a> to apply a <code>focus-visible</code> class to other components if needed.",
"sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/basics/#the-sx-prop\">`sx` page</a> for more details."
},
"classDescriptions": {
"root": { "description": "Styles applied to the root element." },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import { SxProps } from '@material-ui/system';
import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase';
import { OverrideProps } from '../OverridableComponent';
import { Theme } from '..';

export type AccordionSummaryTypeMap<
P = {},
Expand Down Expand Up @@ -32,6 +34,10 @@ export type AccordionSummaryTypeMap<
* The icon to display as the expand indicator.
*/
expandIcon?: React.ReactNode;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
};
defaultComponent: D;
}>;
Expand Down
202 changes: 131 additions & 71 deletions packages/material-ui/src/AccordionSummary/AccordionSummary.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,127 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { deepmerge } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import ButtonBase from '../ButtonBase';
import withStyles from '../styles/withStyles';
import AccordionContext from '../Accordion/AccordionContext';
import accordionSummaryClasses, {
getAccordionSummaryUtilityClass,
} from './accordionSummaryClasses';

export const styles = (theme) => {
const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(styles.root || {}, {
...(styleProps.expanded && styles.expanded),
[`&.${accordionSummaryClasses.focusVisible}`]: styles.focusVisible,
...(styleProps.disabled && styles.disabled),
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
[`& .${accordionSummaryClasses.content}`]: styles.content,
[`& .${accordionSummaryClasses.expandIconWrapper}`]: styles.expandIconWrapper,
});
};

const useUtilityClasses = (styleProps) => {
const { classes, expanded, disabled } = styleProps;

const slots = {
root: ['root', expanded && 'expanded', disabled && 'disabled'],
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
content: ['content', expanded && 'expanded'],
expandIcon: ['expandIcon', expanded && 'expanded'],
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
};

return composeClasses(slots, getAccordionSummaryUtilityClass, classes);
};

const AccordionSummaryRoot = experimentalStyled(
ButtonBase,
{},
{
name: 'MuiAccordionSummary',
slot: 'Root',
overridesResolver,
},
)(({ theme, styleProps }) => {
const transition = {
duration: theme.transitions.duration.shortest,
};

return {
/* Styles applied to the root element. */
root: {
display: 'flex',
minHeight: 8 * 6,
transition: theme.transitions.create(['min-height', 'background-color'], transition),
padding: theme.spacing(0, 2),
'&:hover:not($disabled)': {
cursor: 'pointer',
},
'&$expanded': {
minHeight: 64,
},
'&$focusVisible': {
backgroundColor: theme.palette.action.focus,
},
'&$disabled': {
opacity: theme.palette.action.disabledOpacity,
},
display: 'flex',
minHeight: 8 * 6,
transition: theme.transitions.create(['min-height', 'background-color'], transition),
padding: theme.spacing(0, 2),
/* Styles applied to the root element if `expanded={true}`. */
...(styleProps.expanded && {
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
minHeight: 64,
}),
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
/* Styles applied to the ButtonBase root element if the button is keyboard focused. */
[`&.${accordionSummaryClasses.focusVisible}`]: {
backgroundColor: theme.palette.action.focus,
},
/* Pseudo-class applied to the root element, children wrapper element and `IconButton` component if `expanded={true}`. */
expanded: {},
/* Pseudo-class applied to the ButtonBase root element if the button is keyboard focused. */
focusVisible: {},
/* Pseudo-class applied to the root element if `disabled={true}`. */
disabled: {},
/* Styles applied to the root element if `disabled={true}`. */
...(styleProps.disabled
? { opacity: theme.palette.action.disabledOpacity }
: { '&:hover': { cursor: 'pointer' } }),
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
};
});

const AccordionSummaryContent = experimentalStyled(
'div',
{},
{
name: 'MuiAccordionSummary',
slot: 'Content',
},
)(({ theme, styleProps }) => {
const transition = {
duration: theme.transitions.duration.shortest,
};

return {
/* Styles applied to the children wrapper element. */
content: {
display: 'flex',
flexGrow: 1,
transition: theme.transitions.create(['margin'], transition),
margin: '12px 0',
'&$expanded': {
margin: '20px 0',
},
},
display: 'flex',
flexGrow: 1,
transition: theme.transitions.create(['margin'], transition),
margin: '12px 0',
/* Styles applied to the children wrapper element if `expanded={true}`. */
...(styleProps.expanded && {
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
margin: '20px 0',
}),
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
};
});

const AccordionSummaryExpandIconWrapper = experimentalStyled(
'div',
{},
{
name: 'MuiAccordionSummary',
slot: 'ExpandIconWrapper',
},
)(({ theme, styleProps }) => {
const transition = {
duration: theme.transitions.duration.shortest,
};

return {
/* Styles applied to the `expandIcon`'s wrapper element. */
expandIconWrapper: {
display: 'flex',
color: theme.palette.action.active,
transform: 'rotate(0deg)',
transition: theme.transitions.create('transform', transition),
'&$expanded': {
transform: 'rotate(180deg)',
},
},
display: 'flex',
color: theme.palette.action.active,
transform: 'rotate(0deg)',
transition: theme.transitions.create('transform', transition),
/* Styles applied to the `expandIcon`'s wrapper element if `expanded={true}`. */
...(styleProps.expanded && {
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
transform: 'rotate(180deg)',
}),
queengooborg marked this conversation as resolved.
Show resolved Hide resolved
};
};
});

const AccordionSummary = React.forwardRef(function AccordionSummary(props, ref) {
const {
children,
classes,
className,
expandIcon,
focusVisibleClassName,
onClick,
...other
} = props;
const AccordionSummary = React.forwardRef(function AccordionSummary(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiAccordionSummary' });
const { children, className, expandIcon, focusVisibleClassName, onClick, ...other } = props;

const { disabled = false, expanded, toggle } = React.useContext(AccordionContext);
const handleChange = (event) => {
Expand All @@ -80,37 +133,40 @@ const AccordionSummary = React.forwardRef(function AccordionSummary(props, ref)
}
};

const styleProps = {
...props,
expanded,
disabled,
};

const classes = useUtilityClasses(styleProps);

return (
<ButtonBase
<AccordionSummaryRoot
focusRipple={false}
disableRipple
disabled={disabled}
component="div"
aria-expanded={expanded}
className={clsx(
classes.root,
{
[classes.disabled]: disabled,
[classes.expanded]: expanded,
},
className,
)}
className={clsx(classes.root, className)}
focusVisibleClassName={clsx(classes.focusVisible, focusVisibleClassName)}
onClick={handleChange}
ref={ref}
styleProps={styleProps}
{...other}
>
<div className={clsx(classes.content, { [classes.expanded]: expanded })}>{children}</div>
<AccordionSummaryContent className={classes.content} styleProps={styleProps}>
{children}
</AccordionSummaryContent>
{expandIcon && (
<div
className={clsx(classes.expandIconWrapper, {
[classes.expanded]: expanded,
})}
<AccordionSummaryExpandIconWrapper
className={classes.expandIconWrapper}
styleProps={styleProps}
>
{expandIcon}
</div>
</AccordionSummaryExpandIconWrapper>
)}
</ButtonBase>
</AccordionSummaryRoot>
);
});

Expand Down Expand Up @@ -148,6 +204,10 @@ AccordionSummary.propTypes = {
* @ignore
*/
onClick: PropTypes.func,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiAccordionSummary' })(AccordionSummary);
export default AccordionSummary;
21 changes: 6 additions & 15 deletions packages/material-ui/src/AccordionSummary/AccordionSummary.test.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import {
getClasses,
createMount,
describeConformance,
act,
createClientRender,
fireEvent,
} from 'test/utils';
import { createMount, describeConformanceV5, act, createClientRender, fireEvent } from 'test/utils';
import Accordion from '../Accordion';
import AccordionSummary from './AccordionSummary';
import ButtonBase from '../ButtonBase';
import classes from './accordionSummaryClasses';

describe('<AccordionSummary />', () => {
const mount = createMount();
let classes;
const render = createClientRender();

before(() => {
classes = getClasses(<AccordionSummary />);
});

describeConformance(<AccordionSummary />, () => ({
describeConformanceV5(<AccordionSummary />, () => ({
classes,
inheritComponent: ButtonBase,
mount,
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
muiName: 'MuiAccordionSummary',
testVariantProps: { disabled: true },
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
skip: ['componentProp', 'componentsProp'],
}));

it('renders the children inside the .content element', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface AccordionSummaryClasses {
root: string;
expanded: string;
focusVisible: string;
disabled: string;
content: string;
expandIconWrapper: string;
}

declare const accordionSummaryClasses: AccordionSummaryClasses;

export function getAccordionSummaryUtilityClass(slot: string): string;

export default accordionSummaryClasses;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getAccordionSummaryUtilityClass(slot) {
return generateUtilityClass('MuiAccordionSummary', slot);
}

const accordionSummaryClasses = generateUtilityClasses('MuiAccordionSummary', [
'root',
'expanded',
'focusVisible',
'disabled',
'content',
'expandIconWrapper',
]);

export default accordionSummaryClasses;
3 changes: 3 additions & 0 deletions packages/material-ui/src/AccordionSummary/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default } from './AccordionSummary';
export * from './AccordionSummary';

export { default as accordionSummaryClasses } from './accordionSummaryClasses';
export * from './accordionSummaryClasses';
3 changes: 3 additions & 0 deletions packages/material-ui/src/AccordionSummary/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export { default } from './AccordionSummary';

export { default as accordionSummaryClasses } from './accordionSummaryClasses';
export * from './accordionSummaryClasses';