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

[Tab] Migrate TabScrollButton to emotion #24654

Merged
merged 5 commits into from Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/pages/api-docs/tab-scroll-button.json
Expand Up @@ -10,7 +10,8 @@
},
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" } },
"disabled": { "type": { "name": "bool" } }
"disabled": { "type": { "name": "bool" } },
"sx": { "type": { "name": "object" } }
},
"name": "TabScrollButton",
"styles": {
Expand All @@ -23,6 +24,6 @@
"filename": "/packages/material-ui/src/TabScrollButton/TabScrollButton.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/tabs/\">Tabs</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Expand Up @@ -5,7 +5,8 @@
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"direction": "The direction the button should indicate.",
"disabled": "If <code>true</code>, the component is disabled.",
"orientation": "The component orientation (layout flow direction)."
"orientation": "The component orientation (layout flow direction).",
"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
@@ -1,5 +1,6 @@
import { SxProps } from '@material-ui/system';
import * as React from 'react';
import { InternalStandardProps as StandardProps } from '..';
import { InternalStandardProps as StandardProps, Theme } from '..';

export interface TabScrollButtonProps extends StandardProps<React.HTMLAttributes<HTMLDivElement>> {
/**
Expand Down Expand Up @@ -29,6 +30,10 @@ export interface TabScrollButtonProps extends StandardProps<React.HTMLAttributes
* The component orientation (layout flow direction).
*/
orientation: 'horizontal' | 'vertical';
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
}

export type TabScrollButtonClassKey = keyof NonNullable<TabScrollButtonProps['classes']>;
Expand Down
85 changes: 58 additions & 27 deletions packages/material-ui/src/TabScrollButton/TabScrollButton.js
Expand Up @@ -2,49 +2,76 @@
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 KeyboardArrowLeft from '../internal/svg-icons/KeyboardArrowLeft';
import KeyboardArrowRight from '../internal/svg-icons/KeyboardArrowRight';
import withStyles from '../styles/withStyles';
import ButtonBase from '../ButtonBase';

export const styles = {
import useThemeProps from '../styles/useThemeProps';
import experimentalStyled from '../styles/experimentalStyled';
import { getTabScrollButtonUtilityClass } from './tabScrollButtonClasses';

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

return deepmerge(styles.root || {}, {
...(styleProps.orientation && styles[styleProps.orientation]),
});
};

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

const slots = {
root: ['root', orientation, disabled && 'disabled'],
};

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

const TabScrollButtonRoot = experimentalStyled(
ButtonBase,
{},
{
name: 'MuiTabScrollButton',
slot: 'Root',
overridesResolver,
},
)(({ styleProps }) => ({
/* Styles applied to the root element. */
root: {
width: 40,
flexShrink: 0,
opacity: 0.8,
'&$disabled': {
opacity: 0,
},
width: 40,
flexShrink: 0,
opacity: 0.8,
'&.Mui-disabled': {
opacity: 0,
},
/* Styles applied to the root element if `orientation="vertical"`. */
vertical: {
...(styleProps.orientation === 'vertical' && {
width: '100%',
height: 40,
'& svg': {
transform: 'rotate(90deg)',
},
},
/* Pseudo-class applied to the root element if `disabled={true}`. */
disabled: {},
};
}),
}));

const TabScrollButton = React.forwardRef(function TabScrollButton(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiTabScrollButton' });
const { className, direction, orientation, disabled, ...other } = props;

const TabScrollButton = React.forwardRef(function TabScrollButton(props, ref) {
const { classes, className: classNameProp, direction, orientation, disabled, ...other } = props;
// TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed
const styleProps = { ...props };

const classes = useUtilityClasses(styleProps);

return (
<ButtonBase
<TabScrollButtonRoot
component="div"
className={clsx(
classes.root,
{
[classes.vertical]: orientation === 'vertical',
[classes.disabled]: disabled,
},
classNameProp,
)}
className={clsx(classes.root, className)}
ref={ref}
role={null}
styleProps={styleProps}
tabIndex={null}
{...other}
>
Expand All @@ -53,7 +80,7 @@ const TabScrollButton = React.forwardRef(function TabScrollButton(props, ref) {
) : (
<KeyboardArrowRight fontSize="small" />
)}
</ButtonBase>
</TabScrollButtonRoot>
);
});

Expand Down Expand Up @@ -86,6 +113,10 @@ TabScrollButton.propTypes = {
* The component orientation (layout flow direction).
*/
orientation: PropTypes.oneOf(['horizontal', 'vertical']).isRequired,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTabScrollButton' })(TabScrollButton);
export default TabScrollButton;
13 changes: 6 additions & 7 deletions packages/material-ui/src/TabScrollButton/TabScrollButton.test.js
@@ -1,26 +1,25 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils';
import { createMount, createClientRender, describeConformanceV5 } from 'test/utils';
import TabScrollButton from './TabScrollButton';
import classes from './tabScrollButtonClasses';

describe('<TabScrollButton />', () => {
const defaultProps = {
direction: 'left',
orientation: 'horizontal',
};
const render = createClientRender();
let classes;
const mount = createMount();

before(() => {
classes = getClasses(<TabScrollButton {...defaultProps} />);
});

describeConformance(<TabScrollButton {...defaultProps} />, () => ({
describeConformanceV5(<TabScrollButton {...defaultProps} />, () => ({
classes,
inheritComponent: 'div',
mount,
muiName: 'MuiTabScrollButton',
testVariantProps: { orientation: 'vertical' },
refInstanceof: window.HTMLDivElement,
skip: ['componentProp', 'componentsProp'],
}));

it('should render as a button with the root class', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/TabScrollButton/index.d.ts
@@ -1,2 +1,5 @@
export { default } from './TabScrollButton';
export * from './TabScrollButton';

export { default as tabScrollButtonClasses } from './tabScrollButtonClasses';
export * from './tabScrollButtonClasses';
3 changes: 3 additions & 0 deletions packages/material-ui/src/TabScrollButton/index.js
@@ -1 +1,4 @@
export { default } from './TabScrollButton';

export { default as tabScrollButtonClasses } from './tabScrollButtonClasses';
export * from './tabScrollButtonClasses';
@@ -0,0 +1,12 @@
export interface TabScrollButtonClasses {
root: string;
vertical: string;
horizontal: string;
disabled: string;
}

declare const tabScrollButtonClasses: TabScrollButtonClasses;

export function getTabScrollButtonUtilityClass(slot: string): string;

export default tabScrollButtonClasses;
14 changes: 14 additions & 0 deletions packages/material-ui/src/TabScrollButton/tabScrollButtonClasses.js
@@ -0,0 +1,14 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getTabScrollButtonUtilityClass(slot) {
return generateUtilityClass('MuiTabScrollButton', slot);
}

const tabScrollButtonClasses = generateUtilityClasses('MuiTabScrollButton', [
'root',
'vertical',
'horizontal',
'disabled',
]);

export default tabScrollButtonClasses;