Skip to content

Commit

Permalink
[TextField] Migrate to emotion (#25286)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasznguyen committed Mar 14, 2021
1 parent 2587f64 commit 89f610f
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 24 deletions.
3 changes: 2 additions & 1 deletion docs/pages/api-docs/text-field.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"description": "'medium'<br>&#124;&nbsp;'small'<br>&#124;&nbsp;string"
}
},
"sx": { "type": { "name": "object" } },
"type": { "type": { "name": "string" } },
"value": { "type": { "name": "any" } },
"variant": {
Expand All @@ -62,6 +63,6 @@
"filename": "/packages/material-ui/src/TextField/TextField.js",
"inheritance": { "component": "FormControl", "pathname": "/api/form-control/" },
"demos": "<ul><li><a href=\"/components/autocomplete/\">Autocomplete</a></li>\n<li><a href=\"/components/pickers/\">Pickers</a></li>\n<li><a href=\"/components/text-fields/\">Text Fields</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/translations/api-docs/text-field/text-field.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"select": "Render a <a href=\"/api/select/\"><code>Select</code></a> element while passing the Input element to <code>Select</code> as <code>input</code> parameter. If this option is set you must pass the options of the select as children.",
"SelectProps": "Props applied to the <a href=\"/api/select/\"><code>Select</code></a> element.",
"size": "The size of the component.",
"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.",
"type": "Type of the <code>input</code> element. It should be <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types\">a valid HTML5 input type</a>.",
"value": "The value of the <code>input</code> element, required for a controlled component.",
"variant": "The variant to use."
Expand Down
1 change: 1 addition & 0 deletions framer/scripts/framerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ export const componentSettings = {
'value',
'size',
'color',
'sx',
],
propValues: {
helperText: "''",
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/TextField/TextField.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { SxProps } from '@material-ui/system';
import { OverridableStringUnion } from '@material-ui/types';
import { InternalStandardProps as StandardProps } from '..';
import { FormControlProps } from '../FormControl';
Expand All @@ -9,6 +10,7 @@ import { FilledInputProps } from '../FilledInput';
import { OutlinedInputProps } from '../OutlinedInput';
import { InputLabelProps } from '../InputLabel';
import { SelectProps } from '../Select';
import { Theme } from '../styles';

export interface TextFieldPropsColorOverrides {}
export interface TextFieldPropsSizeOverrides {}
Expand Down Expand Up @@ -143,6 +145,10 @@ export interface BaseTextFieldProps
* The size of the component.
*/
size?: OverridableStringUnion<Record<'small' | 'medium', true>, TextFieldPropsSizeOverrides>;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
/**
* Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
*/
Expand Down
62 changes: 52 additions & 10 deletions packages/material-ui/src/TextField/TextField.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,49 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { refType } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import { deepmerge, refType } from '@material-ui/utils';
import experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import Input from '../Input';
import FilledInput from '../FilledInput';
import OutlinedInput from '../OutlinedInput';
import InputLabel from '../InputLabel';
import FormControl from '../FormControl';
import FormHelperText from '../FormHelperText';
import Select from '../Select';
import withStyles from '../styles/withStyles';
import { getTextFieldUtilityClass } from './textFieldClasses';

const variantComponent = {
standard: Input,
filled: FilledInput,
outlined: OutlinedInput,
};

export const styles = {
/* Styles applied to the root element. */
root: {},
const overridesResolver = (props, styles) => {
return deepmerge(styles.root || {}, {});
};

const useUtilityClasses = (styleProps) => {
const { classes } = styleProps;

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

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

const TextFieldRoot = experimentalStyled(
FormControl,
{},
{
name: 'MuiTextField',
slot: 'Root',
overridesResolver,
},
)({});

/**
* The `TextField` is a convenience wrapper for the most common cases (80%).
* It cannot be all things to all people, otherwise the API would grow out of control.
Expand Down Expand Up @@ -54,12 +76,12 @@ export const styles = {
* - using the upper case props for passing values directly to the components
* - using the underlying components directly as shown in the demos
*/
const TextField = React.forwardRef(function TextField(props, ref) {
const TextField = React.forwardRef(function TextField(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiTextField' });
const {
autoComplete,
autoFocus = false,
children,
classes,
className,
color = 'primary',
defaultValue,
Expand Down Expand Up @@ -92,6 +114,21 @@ const TextField = React.forwardRef(function TextField(props, ref) {
...other
} = props;

const styleProps = {
...props,
autoFocus,
color,
disabled,
error,
fullWidth,
multiline,
required,
select,
variant,
};

const classes = useUtilityClasses(styleProps);

if (process.env.NODE_ENV !== 'production') {
if (select && !children) {
console.error(
Expand Down Expand Up @@ -154,7 +191,7 @@ const TextField = React.forwardRef(function TextField(props, ref) {
);

return (
<FormControl
<TextFieldRoot
className={clsx(classes.root, className)}
disabled={disabled}
error={error}
Expand All @@ -163,6 +200,7 @@ const TextField = React.forwardRef(function TextField(props, ref) {
required={required}
color={color}
variant={variant}
styleProps={styleProps}
{...other}
>
{label && (
Expand Down Expand Up @@ -191,7 +229,7 @@ const TextField = React.forwardRef(function TextField(props, ref) {
{helperText}
</FormHelperText>
)}
</FormControl>
</TextFieldRoot>
);
});

Expand Down Expand Up @@ -353,6 +391,10 @@ TextField.propTypes /* remove-proptypes */ = {
PropTypes.oneOf(['medium', 'small']),
PropTypes.string,
]),
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
/**
* Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
*/
Expand All @@ -368,4 +410,4 @@ TextField.propTypes /* remove-proptypes */ = {
variant: PropTypes.oneOf(['filled', 'outlined', 'standard']),
};

export default withStyles(styles, { name: 'MuiTextField' })(TextField);
export default TextField;
24 changes: 11 additions & 13 deletions packages/material-ui/src/TextField/TextField.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils';
import FormControl from '../FormControl';
import TextField from './TextField';
import MenuItem from '../MenuItem';
import { inputBaseClasses } from '../InputBase';
import { outlinedInputClasses } from '../OutlinedInput';
import { createMount, createClientRender, describeConformanceV5 } from 'test/utils';
import FormControl from '@material-ui/core/FormControl';
import { inputBaseClasses } from '@material-ui/core/InputBase';
import MenuItem from '@material-ui/core/MenuItem';
import { outlinedInputClasses } from '@material-ui/core/OutlinedInput';
import TextField, { textFieldClasses as classes } from '@material-ui/core/TextField';

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

before(() => {
classes = getClasses(<TextField variant="standard" />);
});

describeConformance(<TextField variant="standard" />, () => ({
describeConformanceV5(<TextField variant="standard" />, () => ({
classes,
inheritComponent: FormControl,
render,
mount,
muiName: 'MuiTextField',
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
testVariantProps: { variant: 'outlined' },
skip: ['componentProp', 'componentsProp'],
}));

describe('structure', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/TextField/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export { default } from './TextField';

export { default as textFieldClasses } from './textFieldClasses';
export * from './textFieldClasses';
7 changes: 7 additions & 0 deletions packages/material-ui/src/TextField/textFieldClasses.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { TextFieldClassKey } from './TextField';

declare const textFieldClasses: Record<TextFieldClassKey, string>;

export function getTextFieldUtilityClass(slot: string): string;

export default textFieldClasses;
9 changes: 9 additions & 0 deletions packages/material-ui/src/TextField/textFieldClasses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getTextFieldUtilityClass(slot) {
return generateUtilityClass('MuiTextField', slot);
}

const textFieldClasses = generateUtilityClasses('MuiTextField', ['root']);

export default textFieldClasses;

0 comments on commit 89f610f

Please sign in to comment.