Skip to content

Commit

Permalink
[TextField] Migrate OutlinedInput to emotion (#24688)
Browse files Browse the repository at this point in the history
  • Loading branch information
duganbrett committed Feb 17, 2021
1 parent 237c38e commit 53ec59a
Show file tree
Hide file tree
Showing 18 changed files with 244 additions and 237 deletions.
3 changes: 2 additions & 1 deletion docs/pages/api-docs/outlined-input.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"required": { "type": { "name": "bool" } },
"rows": { "type": { "name": "union", "description": "number<br>&#124;&nbsp;string" } },
"startAdornment": { "type": { "name": "node" } },
"sx": { "type": { "name": "object" } },
"type": { "type": { "name": "string" }, "default": "'text'" },
"value": { "type": { "name": "any" } }
},
Expand Down Expand Up @@ -57,6 +58,6 @@
"filename": "/packages/material-ui/src/OutlinedInput/OutlinedInput.js",
"inheritance": { "component": "InputBase", "pathname": "/api/input-base/" },
"demos": "<ul><li><a href=\"/components/text-fields/\">Text Fields</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"required": "If <code>true</code>, the <code>input</code> element is required. The prop defaults to the value (<code>false</code>) inherited from the parent FormControl component.",
"rows": "Number of rows to display when multiline option is set to true.",
"startAdornment": "Start <code>InputAdornment</code> for this 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."
},
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui/src/Autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const AutocompleteRoot = experimentalStyled(
padding: '2px 4px 3px 0',
},
},
'&[class*="MuiOutlinedInput-root"]': {
'&.MuiOutlinedInput-root': {
padding: 9,
[`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {
paddingRight: 26 + 4 + 9,
Expand All @@ -174,7 +174,7 @@ const AutocompleteRoot = experimentalStyled(
right: 9,
},
},
'&[class*="MuiOutlinedInput-root"][class*="MuiOutlinedInput-sizeSmall"]': {
'&.MuiOutlinedInput-root.MuiInputBase-sizeSmall': {
padding: 6,
[`& .${autocompleteClasses.input}`]: {
padding: '2.5px 4px 2.5px 6px',
Expand Down
18 changes: 2 additions & 16 deletions packages/material-ui/src/Breadcrumbs/BreadcrumbCollapsed.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@ import { emphasize } from '../styles/colorManipulator';
import MoreHorizIcon from '../internal/svg-icons/MoreHoriz';
import ButtonBase from '../ButtonBase';

const BreadcrumbCollapsedButton = experimentalStyled(
ButtonBase,
{},
{
name: 'PrivateBreadcrumbCollapsed',
slot: 'Button',
},
)(({ theme }) => ({
const BreadcrumbCollapsedButton = experimentalStyled(ButtonBase)(({ theme }) => ({
display: 'flex',
marginLeft: theme.spacing(0.5),
marginRight: theme.spacing(0.5),
Expand All @@ -33,14 +26,7 @@ const BreadcrumbCollapsedButton = experimentalStyled(
},
}));

const BreadcrumbCollapsedIcon = experimentalStyled(
MoreHorizIcon,
{},
{
name: 'PrivateBreadcrumbCollapsed',
slot: 'Icon',
},
)({
const BreadcrumbCollapsedIcon = experimentalStyled(MoreHorizIcon)({
width: 24,
height: 16,
});
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui/src/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ const useUtilityClasses = (styleProps) => {
root: ['root', indeterminate && 'indeterminate', `color${capitalize(color)}`],
};

const finalClasses = composeClasses(slots, getCheckboxUtilityClass, classes);
const composedClasses = composeClasses(slots, getCheckboxUtilityClass, classes);

return {
...classes, // forward the disabled and checked classes to the SwitchBase
...finalClasses,
...composedClasses,
};
};

Expand Down
17 changes: 8 additions & 9 deletions packages/material-ui/src/Input/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ const useUtilityClasses = (styleProps) => {
input: ['input'],
};

return composeClasses(slots, getInputUtilityClass, classes);
const composedClasses = composeClasses(slots, getInputUtilityClass, classes);

return {
...classes, // forward classes to the InputBase
...composedClasses,
};
};

const InputRoot = experimentalStyled(
Expand Down Expand Up @@ -107,16 +112,10 @@ const Input = React.forwardRef(function Input(inProps, ref) {
...other
} = props;

const styleProps = {
...props,
fullWidth,
inputComponent,
multiline,
type,
};

const classes = useUtilityClasses(props);

const styleProps = { disableUnderline };

return (
<InputBase
components={{ Root: InputRoot }}
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui/src/InputLabel/InputLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ const useUtilityClasses = (styleProps) => {
],
};

const finalClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);

return {
...classes, // forward the focused, disabled, etc. classes to the FormLabel
...finalClasses,
...composedClasses,
};
};

Expand Down
140 changes: 66 additions & 74 deletions packages/material-ui/src/OutlinedInput/NotchedOutline.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,66 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import useTheme from '../styles/useTheme';
import capitalize from '../utils/capitalize';
import experimentalStyled from '../styles/experimentalStyled';

export const styles = (theme) => {
return {
/* Styles applied to the root element. */
root: {
textAlign: 'left',
position: 'absolute',
bottom: 0,
right: 0,
top: -5,
left: 0,
margin: 0,
padding: '0 8px',
pointerEvents: 'none',
borderRadius: 'inherit',
borderStyle: 'solid',
borderWidth: 1,
overflow: 'hidden',
},
/* Styles applied to the legend element when `labelWidth` is provided. */
legend: {
padding: 0,
lineHeight: '11px', // sync with `height` in `legend` styles
transition: theme.transitions.create('width', {
duration: 150,
easing: theme.transitions.easing.easeOut,
}),
},
/* Styles applied to the legend element. */
legendLabelled: {
display: 'block',
width: 'auto',
padding: 0,
height: 11, // sync with `lineHeight` in `legend` styles
fontSize: '0.75em',
visibility: 'hidden',
maxWidth: 0.01,
transition: theme.transitions.create('max-width', {
duration: 50,
easing: theme.transitions.easing.easeOut,
}),
'& > span': {
paddingLeft: 5,
paddingRight: 5,
display: 'inline-block',
},
const NotchedOutlineRoot = experimentalStyled('fieldset')({
textAlign: 'left',
position: 'absolute',
bottom: 0,
right: 0,
top: -5,
left: 0,
margin: 0,
padding: '0 8px',
pointerEvents: 'none',
borderRadius: 'inherit',
borderStyle: 'solid',
borderWidth: 1,
overflow: 'hidden',
});

const NotchedOutlineLegend = experimentalStyled('legend')(({ styleProps, theme }) => ({
...(styleProps.label === undefined && {
padding: 0,
lineHeight: '11px', // sync with `height` in `legend` styles
transition: theme.transitions.create('width', {
duration: 150,
easing: theme.transitions.easing.easeOut,
}),
}),
...(styleProps.label !== undefined && {
display: 'block',
width: 'auto',
padding: 0,
height: 11, // sync with `lineHeight` in `legend` styles
fontSize: '0.75em',
visibility: 'hidden',
maxWidth: 0.01,
transition: theme.transitions.create('max-width', {
duration: 50,
easing: theme.transitions.easing.easeOut,
}),
'& > span': {
paddingLeft: 5,
paddingRight: 5,
display: 'inline-block',
},
/* Styles applied to the legend element is notched. */
legendNotched: {
...(styleProps.notched && {
maxWidth: 1000,
transition: theme.transitions.create('max-width', {
duration: 100,
easing: theme.transitions.easing.easeOut,
delay: 50,
}),
},
};
};
}),
}),
}));

/**
* @ignore - internal component.
*/
const NotchedOutline = React.forwardRef(function NotchedOutline(props, ref) {
export default function NotchedOutline(props) {
const {
children,
classes,
Expand All @@ -79,21 +73,21 @@ const NotchedOutline = React.forwardRef(function NotchedOutline(props, ref) {
} = props;
const theme = useTheme();
const align = theme.direction === 'rtl' ? 'right' : 'left';

const styleProps = {
...props,
notched,
label,
};
if (label !== undefined) {
return (
<fieldset
<NotchedOutlineRoot
aria-hidden
className={clsx(classes.root, className)}
ref={ref}
className={className}
style={style}
styleProps={styleProps}
{...other}
>
<legend
className={clsx(classes.legendLabelled, {
[classes.legendNotched]: notched,
})}
>
<NotchedOutlineLegend styleProps={styleProps}>
{/* Use the nominal use case of the legend, avoid rendering artefacts. */}
{label ? (
<span>{label}</span>
Expand All @@ -102,27 +96,27 @@ const NotchedOutline = React.forwardRef(function NotchedOutline(props, ref) {
// eslint-disable-next-line react/no-danger
<span className="notranslate" dangerouslySetInnerHTML={{ __html: '&#8203;' }} />
)}
</legend>
</fieldset>
</NotchedOutlineLegend>
</NotchedOutlineRoot>
);
}

const labelWidth = labelWidthProp > 0 ? labelWidthProp * 0.75 + 8 : 0.01;

// TODO remove this branch
return (
<fieldset
<NotchedOutlineRoot
aria-hidden
style={{
[`padding${capitalize(align)}`]: 8,
...style,
}}
className={clsx(classes.root, className)}
ref={ref}
className={className}
styleProps={styleProps}
{...other}
>
<legend
className={classes.legend}
<NotchedOutlineLegend
styleProps={styleProps}
style={{
// IE11: fieldset with legend does not render
// a border radius. This maintains consistency
Expand All @@ -134,10 +128,10 @@ const NotchedOutline = React.forwardRef(function NotchedOutline(props, ref) {
{/* notranslate needed while Google Translate will not fix zero-width space issue */}
{/* eslint-disable-next-line react/no-danger */}
<span className="notranslate" dangerouslySetInnerHTML={{ __html: '&#8203;' }} />
</legend>
</fieldset>
</NotchedOutlineLegend>
</NotchedOutlineRoot>
);
});
}

NotchedOutline.propTypes = {
/**
Expand Down Expand Up @@ -170,5 +164,3 @@ NotchedOutline.propTypes = {
*/
style: PropTypes.object,
};

export default withStyles(styles, { name: 'PrivateNotchedOutline' })(NotchedOutline);
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createClientRender } from 'test/utils';
import { createClientRender } from 'test/utils';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import NotchedOutline from './NotchedOutline';

describe('<NotchedOutline />', () => {
const render = createClientRender();

let classes;
const defaultProps = {
labelWidth: 36,
notched: true,
label: 'My label',
};

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

it('should pass props', () => {
const { container } = render(
<NotchedOutline
Expand All @@ -31,7 +26,6 @@ describe('<NotchedOutline />', () => {

expect(container.querySelector('fieldset')).to.have.class('notched-outline');
expect(container.querySelector('fieldset').style.width).to.equal('17px');
expect(container.querySelector('legend')).to.have.class(classes.legendNotched);
});

it('should set alignment rtl', () => {
Expand Down
7 changes: 6 additions & 1 deletion packages/material-ui/src/OutlinedInput/OutlinedInput.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { InternalStandardProps as StandardProps } from '..';
import { SxProps } from '@material-ui/system';
import { InternalStandardProps as StandardProps, Theme } from '..';
import { InputBaseProps } from '../InputBase';

export interface OutlinedInputProps extends StandardProps<InputBaseProps> {
Expand Down Expand Up @@ -53,6 +54,10 @@ export interface OutlinedInputProps extends StandardProps<InputBaseProps> {
* If `true`, the outline is notched to accommodate the label.
*/
notched?: boolean;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
}

export type OutlinedInputClassKey = keyof NonNullable<OutlinedInputProps['classes']>;
Expand Down
Loading

0 comments on commit 53ec59a

Please sign in to comment.