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

[Table] Use makeStyles over withStyles #15023

Closed
Closed
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
30 changes: 20 additions & 10 deletions docs/scripts/buildApi.js
Expand Up @@ -73,6 +73,9 @@ function getInheritance(src) {
};
}

const stylesRegexp = /const styles.*[\r\n](.*[\r\n])*};[\r\n][\r\n]/;
const styleRegexp = /\/\* (.*) \*\/[\r\n]\s*(\w*)/g;

function buildDocs(options) {
const { component: componentObject, pagesMarkdown } = options;
const src = readFileSync(componentObject.filename, 'utf8');
Expand All @@ -92,11 +95,11 @@ function buildDocs(options) {
descriptions: {},
};

if (component.styles && component.default.options) {
if ((component.styles && component.default.options) || component.default.stylesOrCreator) {
// Collect the customization points of the `classes` property.
styles.classes = Object.keys(getStylesCreator(component.styles).create(theme)).filter(
className => !className.match(/^(@media|@keyframes)/),
);
styles.classes = Object.keys(
getStylesCreator(component.styles || component.default.stylesOrCreator).create(theme),
).filter(className => !className.match(/^(@media|@keyframes)/));
styles.name = component.default.options.name;

let styleSrc = src;
Expand All @@ -111,12 +114,7 @@ function buildDocs(options) {
);
}

/**
* Collect classes comments from the source
*/
const stylesRegexp = /export const styles.*[\r\n](.*[\r\n])*};[\r\n][\r\n]/;
const styleRegexp = /\/\* (.*) \*\/[\r\n]\s*(\w*)/g;
// Extract the styles section from the source
// Extract the styles section from the source.
const stylesSrc = stylesRegexp.exec(styleSrc);

if (stylesSrc) {
Expand All @@ -137,6 +135,18 @@ function buildDocs(options) {
throw err;
}

const docsDefaultProps = component.default.docsDefaultProps;
if (docsDefaultProps) {
Object.keys(reactAPI.props).forEach(key => {
if (docsDefaultProps.hasOwnProperty(key)) {
const defaultValue = docsDefaultProps[key];
reactAPI.props[key].defaultValue = {
value: typeof defaultValue === 'string' ? `'${defaultValue}'` : `${defaultValue}`,
};
}
});
}

reactAPI.name = name;
reactAPI.styles = styles;
reactAPI.pagesMarkdown = pagesMarkdown;
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/css-in-js/api/api.md
Expand Up @@ -54,7 +54,7 @@ style rules to `makeStyles`/`withStyles` which are a function of the `Theme`.
```jsx
import { makeStyles, createStyles } from '@material-ui/styles';

const styles = makeStyles((theme: Theme) => createStyles({
const useStyles = makeStyles((theme: Theme) => createStyles({
root: {
backgroundColor: theme.color.red,
},
Expand Down
80 changes: 79 additions & 1 deletion packages/material-ui-benchmark/src/core.js
@@ -1,10 +1,15 @@
/* eslint-disable no-console */
/* eslint-disable no-console, react/no-array-index-key */

import Benchmark from 'benchmark';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StylesProvider } from '@material-ui/styles';
import ButtonBase from '@material-ui/core/ButtonBase';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';

const suite = new Benchmark.Suite('core', {
onError: event => {
Expand All @@ -13,6 +18,65 @@ const suite = new Benchmark.Suite('core', {
});
Benchmark.options.minSamples = 100;

const data = { name: 'Frozen yoghurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0 };
const rows = Array.from(new Array(100)).map(() => data);

function TableMui() {
return (
<Table>
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell>Calories</TableCell>
<TableCell>Fat (g)</TableCell>
<TableCell>Carbs (g)</TableCell>
<TableCell>Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, index) => (
<TableRow key={index}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell>{row.calories}</TableCell>
<TableCell>{row.fat}</TableCell>
<TableCell>{row.carbs}</TableCell>
<TableCell>{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}

function TableRaw() {
return (
<table>
<thead>
<tr>
<th>Dessert (100g serving)</th>
<th>Calories</th>
<th>Fat (g)</th>
<th>Carbs (g)</th>
<th>Protein (g)</th>
</tr>
</thead>
<tbody>
{rows.map((row, index) => (
<tr key={index}>
<th scope="row">{row.name}</th>
<td>{row.calories}</td>
<td>{row.fat}</td>
<td>{row.carbs}</td>
<td>{row.protein}</td>
</tr>
))}
</tbody>
</table>
);
}

function NakedButton(props) {
return <button type="button" {...props} />;
}
Expand All @@ -26,6 +90,20 @@ class HocButton extends React.Component {
}

suite
.add('TableRaw', () => {
ReactDOMServer.renderToString(
<StylesProvider sheetsCache={null} sheetsManager={new Map()}>
<TableRaw />
</StylesProvider>,
);
})
.add('TableMui', () => {
ReactDOMServer.renderToString(
<StylesProvider sheetsCache={null} sheetsManager={new Map()}>
<TableMui />
</StylesProvider>,
);
})
.add('ButtonBase', () => {
ReactDOMServer.renderToString(
<StylesProvider sheetsManager={new Map()}>
Expand Down
12 changes: 11 additions & 1 deletion packages/material-ui-styles/src/makeStyles/makeStyles.js
Expand Up @@ -207,7 +207,8 @@ function makeStyles(stylesOrCreator, options = {}) {
};
const listenToTheme = stylesCreator.themingEnabled || typeof name === 'string';

return (props = {}) => {
const useStyles = (props = {}) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const theme = (listenToTheme ? useTheme() : null) || defaultTheme;
const stylesOptions = {
...React.useContext(StylesContext),
Expand Down Expand Up @@ -244,6 +245,15 @@ function makeStyles(stylesOrCreator, options = {}) {

return getClasses(instance.current, props.classes, Component);
};

useStyles.options = options;

if (process.env.NODE_ENV !== 'production') {
// For the markdown generation
useStyles.stylesOrCreator = stylesOrCreator;
}

return useStyles;
}

export default makeStyles;
2 changes: 2 additions & 0 deletions packages/material-ui-styles/src/useThemeProps/index.d.ts
@@ -0,0 +1,2 @@
export { default } from './useThemeProps';
export * from './useThemeProps';
1 change: 1 addition & 0 deletions packages/material-ui-styles/src/useThemeProps/index.js
@@ -0,0 +1 @@
export { default } from './useThemeProps';
@@ -0,0 +1 @@
export default function useThemeProps(props: any, options: any): any;
15 changes: 15 additions & 0 deletions packages/material-ui-styles/src/useThemeProps/useThemeProps.js
@@ -0,0 +1,15 @@
import useTheme from '../useTheme';
import getThemeProps from '../getThemeProps';

function useThemeProps(props, options) {
const { defaultTheme, name } = options;
const theme = useTheme() || defaultTheme;
const output = getThemeProps({
theme,
name,
props,
});
return output;
}

export default useThemeProps;
33 changes: 24 additions & 9 deletions packages/material-ui/src/Table/Table.js
@@ -1,8 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import makeStyles from '../styles/makeStyles';
import useThemeProps from '../styles/useThemeProps';
import TableContext from './TableContext';
import muiComponent from '../utils/muiComponent';

export const styles = {
/* Styles applied to the root element. */
Expand All @@ -14,8 +16,19 @@ export const styles = {
},
};

const options = { name: 'MuiTable' };
const useStyles = makeStyles(styles, options);

const Table = React.forwardRef(function Table(props, ref) {
const { classes, className, component: Component, padding, size, ...other } = props;
const {
classes: classesProp,
className,
component: Component = 'table',
padding = 'default',
size = 'medium',
...other
} = useThemeProps(props, options);
const classes = useStyles(props);
const table = React.useMemo(() => ({ padding, size }), [padding, size]);

return (
Expand All @@ -34,7 +47,7 @@ Table.propTypes = {
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object.isRequired,
classes: PropTypes.object,
/**
* @ignore
*/
Expand All @@ -59,10 +72,12 @@ Table.propTypes = {
size: PropTypes.oneOf(['small', 'medium']),
};

Table.defaultProps = {
component: 'table',
padding: 'default',
size: 'medium',
};
if (process.env.NODE_ENV !== 'production') {
Table.docsDefaultProps = {
component: 'table',
padding: 'default',
size: 'medium',
};
}

export default withStyles(styles, { name: 'MuiTable' })(Table);
export default muiComponent(useStyles, Table);
33 changes: 23 additions & 10 deletions packages/material-ui/src/TableBody/TableBody.js
@@ -1,8 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import makeStyles from '../styles/makeStyles';
import useThemeProps from '../styles/useThemeProps';
import Tablelvl2Context from '../Table/Tablelvl2Context';
import muiComponent from '../utils/muiComponent';

const tablelvl2 = {
variant: 'body',
};

export const styles = {
/* Styles applied to the root element. */
Expand All @@ -11,12 +17,17 @@ export const styles = {
},
};

const tablelvl2 = {
variant: 'body',
};
const options = { name: 'MuiTableBody' };
const useStyles = makeStyles(styles, options);

const TableBody = React.forwardRef(function TableBody(props, ref) {
const { classes, className, component: Component, ...other } = props;
const {
classes: classesProp,
className,
component: Component = 'tbody',
...other
} = useThemeProps(props, options);
const classes = useStyles(props);

return (
<Tablelvl2Context.Provider value={tablelvl2}>
Expand All @@ -34,7 +45,7 @@ TableBody.propTypes = {
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object.isRequired,
classes: PropTypes.object,
/**
* @ignore
*/
Expand All @@ -46,8 +57,10 @@ TableBody.propTypes = {
component: PropTypes.elementType,
};

TableBody.defaultProps = {
component: 'tbody',
};
if (process.env.NODE_ENV !== 'production') {
TableBody.docsDefaultProps = {
component: 'tbody',
};
}

export default withStyles(styles, { name: 'MuiTableBody' })(TableBody);
export default muiComponent(useStyles, TableBody);