Skip to content

Commit

Permalink
Merge pull request #3574 from marmelab/use-useStyles
Browse files Browse the repository at this point in the history
[RFR] Use makeStyles in Field Components
  • Loading branch information
fzaninotto authored Aug 22, 2019
2 parents 905ebb7 + 3a61b70 commit 71226da
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 158 deletions.
18 changes: 7 additions & 11 deletions packages/ra-ui-materialui/src/field/BooleanField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import pure from 'recompose/pure';
import FalseIcon from '@material-ui/icons/Clear';
import TrueIcon from '@material-ui/icons/Done';
import Typography, { TypographyProps } from '@material-ui/core/Typography';
import { createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';
import compose from 'recompose/compose';
import { useTranslate } from 'ra-core';

import { FieldProps, InjectedFieldProps, fieldPropTypes } from './types';
import sanitizeRestProps from './sanitizeRestProps';

const styles = createStyles({
const useStyles = makeStyles({
label: {
// Move the text out of the flow of the container.
position: 'absolute',
Expand All @@ -37,19 +37,18 @@ interface Props extends FieldProps {
valueLabelFalse?: string;
}

interface EnhancedProps extends WithStyles<typeof styles> {}

export const BooleanField: SFC<
Props & InjectedFieldProps & EnhancedProps & TypographyProps
Props & InjectedFieldProps & TypographyProps
> = ({
className,
classes,
classes: classesOverride,
source,
record = {},
valueLabelTrue,
valueLabelFalse,
...rest
}) => {
const classes = useStyles({ classes: classesOverride });
const translate = useTranslate();
const value = get(record, source);
let ariaLabel = value ? valueLabelTrue : valueLabelFalse;
Expand Down Expand Up @@ -101,12 +100,9 @@ export const BooleanField: SFC<
};

const EnhancedBooleanField = compose<
Props & InjectedFieldProps & EnhancedProps & TypographyProps,
Props & InjectedFieldProps & TypographyProps,
Props & TypographyProps
>(
pure,
withStyles(styles)
)(BooleanField);
>(pure)(BooleanField);

EnhancedBooleanField.defaultProps = {
addLabel: true,
Expand Down
54 changes: 27 additions & 27 deletions packages/ra-ui-materialui/src/field/ChipField.spec.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import React from 'react';
import assert from 'assert';
import { shallow } from 'enzyme';
import expect from 'expect';
import { ChipField } from './ChipField';
import { render, cleanup } from '@testing-library/react';

describe('<ChipField />', () => {
it('should display the record value added as source', () =>
assert.equal(
shallow(
<ChipField
className="className"
classes={{}}
source="name"
record={{ name: 'foo' }}
/>
).prop('label'),
'foo'
));
afterEach(cleanup);

it('should not display any label added as props', () =>
assert.equal(
shallow(
<ChipField
className="className"
classes={{}}
source="name"
record={{ name: 'foo' }}
label="bar"
/>
).prop('label'),
'foo'
));
it('should display the record value added as source', () => {
const { getByText } = render(
<ChipField
className="className"
classes={{}}
source="name"
record={{ name: 'foo' }}
/>
);
expect(getByText('foo')).not.toBeNull();
});

it('should not display any label added as props', () => {
const { getByText } = render(
<ChipField
className="className"
classes={{}}
source="name"
record={{ name: 'foo' }}
label="bar"
/>
);
expect(getByText('foo')).not.toBeNull();
});
});
37 changes: 21 additions & 16 deletions packages/ra-ui-materialui/src/field/ChipField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@ import compose from 'recompose/compose';
import get from 'lodash/get';
import pure from 'recompose/pure';
import Chip, { ChipProps } from '@material-ui/core/Chip';
import { withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';
import classnames from 'classnames';

import sanitizeRestProps from './sanitizeRestProps';
import { FieldProps, InjectedFieldProps, fieldPropTypes } from './types';

const styles = createStyles({
const useStyles = makeStyles({
chip: { margin: 4 },
});

export const ChipField: SFC<
FieldProps & InjectedFieldProps & WithStyles<typeof styles> & ChipProps
> = ({ className, classes, source, record = {}, ...rest }) => (
<Chip
className={classnames(classes.chip, className)}
label={get(record, source)}
{...sanitizeRestProps(rest)}
/>
);
export const ChipField: SFC<FieldProps & InjectedFieldProps & ChipProps> = ({
className,
classes: classesOverride,
source,
record = {},
...rest
}) => {
const classes = useStyles({ classes: classesOverride });

return (
<Chip
className={classnames(classes.chip, className)}
label={get(record, source)}
{...sanitizeRestProps(rest)}
/>
);
};

const EnhancedChipField = compose<
FieldProps & InjectedFieldProps & WithStyles<typeof styles> & ChipProps,
FieldProps & InjectedFieldProps & ChipProps,
FieldProps & ChipProps
>(
withStyles(styles),
pure
)(ChipField);
>(pure)(ChipField);

EnhancedChipField.defaultProps = {
addLabel: true,
Expand Down
78 changes: 40 additions & 38 deletions packages/ra-ui-materialui/src/field/FileField.spec.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import React from 'react';
import assert from 'assert';
import { shallow } from 'enzyme';
import expect from 'expect';
import { FileField } from './FileField';
import { render, cleanup } from '@testing-library/react';

const defaultProps = {
classes: {},
source: 'url',
};

describe('<FileField />', () => {
afterEach(cleanup);

it('should return an empty div when record is not set', () => {
assert.equal(
shallow(<FileField {...defaultProps} />).html(),
'<div class=""></div>'
);
const { container } = render(<FileField {...defaultProps} />);
expect(container.firstChild.textContent).toEqual('');
});

it('should render a link with correct attributes based on `source` and `title`', () => {
const wrapper = shallow(
const { getByTitle } = render(
<FileField
{...defaultProps}
record={{
Expand All @@ -28,13 +28,13 @@ describe('<FileField />', () => {
/>
);

const link = wrapper.find('a');
assert.equal(link.prop('href'), 'http://foo.com/bar.jpg');
assert.equal(link.prop('title'), 'Hello world!');
const link = getByTitle('Hello world!');
expect(link.href).toEqual('http://foo.com/bar.jpg');
expect(link.title).toEqual('Hello world!');
});

it('should support deep linking', () => {
const wrapper = shallow(
const { getByTitle } = render(
<FileField
{...defaultProps}
record={{
Expand All @@ -48,13 +48,13 @@ describe('<FileField />', () => {
/>
);

const link = wrapper.find('a');
assert.equal(link.prop('href'), 'http://foo.com/bar.jpg');
assert.equal(link.prop('title'), 'Hello world!');
const link = getByTitle('Hello world!');
expect(link.href).toEqual('http://foo.com/bar.jpg');
expect(link.title).toEqual('Hello world!');
});

it('should allow setting static string as title', () => {
const wrapper = shallow(
const { getByTitle } = render(
<FileField
{...defaultProps}
record={{
Expand All @@ -64,27 +64,29 @@ describe('<FileField />', () => {
/>
);

const link = wrapper.find('a');
assert.equal(link.prop('title'), 'Hello world!');
const link = getByTitle('Hello world!');
expect(link.title).toEqual('Hello world!');
});

it('should allow setting target string', () => {
const wrapper = shallow(
const { getByTitle } = render(
<FileField
{...defaultProps}
record={{
url: 'http://foo.com/bar.jpg',
title: 'Hello world!',
}}
target="_blank"
title="title"
/>
);

const link = wrapper.find('a');
assert.equal(link.prop('target'), '_blank');
const link = getByTitle('Hello world!');
expect(link.target).toEqual('_blank');
});

it('should render a list of links with correct attributes based on `src` and `title`', () => {
const wrapper = shallow(
const { getByTitle } = render(
<FileField
{...defaultProps}
record={{
Expand All @@ -105,23 +107,23 @@ describe('<FileField />', () => {
/>
);

const links = wrapper.find('a');
assert.equal(links.at(0).prop('href'), 'http://foo.com/bar.jpg');
assert.equal(links.at(0).prop('title'), 'Hello world!');
assert.equal(links.at(1).prop('href'), 'http://bar.com/foo.jpg');
assert.equal(links.at(1).prop('title'), 'Bye world!');
const firstLink = getByTitle('Hello world!');
const secondLink = getByTitle('Bye world!');
expect(firstLink.href).toEqual('http://foo.com/bar.jpg');
expect(firstLink.title).toEqual('Hello world!');
expect(secondLink.href).toEqual('http://bar.com/foo.jpg');
expect(secondLink.title).toEqual('Bye world!');
});

it('should use custom className', () =>
assert.deepEqual(
shallow(
<FileField
{...defaultProps}
record={{ foo: true }}
source="email"
className="foo"
/>
).prop('className'),
'foo'
));
it('should use custom className', () => {
const { container } = render(
<FileField
{...defaultProps}
record={{ foo: true }}
source="email"
className="foo"
/>
);
expect(container.firstChild.classList.contains('foo')).toBe(true);
});
});
29 changes: 17 additions & 12 deletions packages/ra-ui-materialui/src/field/FileField.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import React, { SFC, ComponentType } from 'react';
import PropTypes from 'prop-types';
import get from 'lodash/get';
import { withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';
import classnames from 'classnames';

import sanitizeRestProps from './sanitizeRestProps';
import { FieldProps, InjectedFieldProps, fieldPropTypes } from './types';

const styles = createStyles({
const useStyles = makeStyles({
root: { display: 'inline-block' },
});

interface Props extends FieldProps {
src?: string;
title?: string;
target?: string;
classes?: object;
}

export const FileField: SFC<
Props & InjectedFieldProps & WithStyles<typeof styles>
> = ({ classes, className, record, source, title, src, target, ...rest }) => {
export const FileField: SFC<Props & InjectedFieldProps> = ({
className,
classes: classesOverride,
record,
source,
title,
src,
target,
...rest
}) => {
const sourceValue = get(record, source);
const classes = useStyles({ classes: classesOverride });

if (!sourceValue) {
return (
Expand Down Expand Up @@ -71,19 +80,15 @@ export const FileField: SFC<
);
};

const EnhancedFileField = withStyles(styles)(FileField) as ComponentType<Props>;

EnhancedFileField.defaultProps = {
FileField.defaultProps = {
addLabel: true,
};

EnhancedFileField.propTypes = {
FileField.propTypes = {
...fieldPropTypes,
src: PropTypes.string,
title: PropTypes.string,
target: PropTypes.string,
};

EnhancedFileField.displayName = 'EnhancedFileField';

export default EnhancedFileField;
export default FileField;
Loading

0 comments on commit 71226da

Please sign in to comment.