diff --git a/docs/pages/api-docs/filled-input.json b/docs/pages/api-docs/filled-input.json
index 75ba88cd2fcea2..9b31ef3631c3dd 100644
--- a/docs/pages/api-docs/filled-input.json
+++ b/docs/pages/api-docs/filled-input.json
@@ -25,6 +25,7 @@
"required": { "type": { "name": "bool" } },
"rows": { "type": { "name": "union", "description": "number
| string" } },
"startAdornment": { "type": { "name": "node" } },
+ "sx": { "type": { "name": "object" } },
"type": { "type": { "name": "string" }, "default": "'text'" },
"value": { "type": { "name": "any" } }
},
@@ -57,6 +58,6 @@
"filename": "/packages/material-ui/src/FilledInput/FilledInput.js",
"inheritance": { "component": "InputBase", "pathname": "/api/input-base/" },
"demos": "
",
- "styledComponent": false,
+ "styledComponent": true,
"cssComponent": false
}
diff --git a/docs/pages/api-docs/input-base.json b/docs/pages/api-docs/input-base.json
index 33a2c33b479849..e5b675c6abd771 100644
--- a/docs/pages/api-docs/input-base.json
+++ b/docs/pages/api-docs/input-base.json
@@ -4,6 +4,11 @@
"autoFocus": { "type": { "name": "bool" } },
"classes": { "type": { "name": "object" } },
"color": { "type": { "name": "enum", "description": "'primary'
| 'secondary'" } },
+ "components": {
+ "type": { "name": "shape", "description": "{ Input?: elementType, Root?: elementType }" },
+ "default": "{}"
+ },
+ "componentsProps": { "type": { "name": "object" }, "default": "{}" },
"defaultValue": { "type": { "name": "any" } },
"disabled": { "type": { "name": "bool" } },
"endAdornment": { "type": { "name": "node" } },
diff --git a/docs/translations/api-docs/filled-input/filled-input.json b/docs/translations/api-docs/filled-input/filled-input.json
index 8eb7f3062d7a1c..ab148a1af6045f 100644
--- a/docs/translations/api-docs/filled-input/filled-input.json
+++ b/docs/translations/api-docs/filled-input/filled-input.json
@@ -26,6 +26,7 @@
"required": "If true
, the input
element is required. The prop defaults to the value (false
) inherited from the parent FormControl component.",
"rows": "Number of rows to display when multiline option is set to true.",
"startAdornment": "Start InputAdornment
for this component.",
+ "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.",
"type": "Type of the input
element. It should be a valid HTML5 input type.",
"value": "The value of the input
element, required for a controlled component."
},
diff --git a/docs/translations/api-docs/input-base/input-base.json b/docs/translations/api-docs/input-base/input-base.json
index 09b6c70c33d863..eb9722b2594774 100644
--- a/docs/translations/api-docs/input-base/input-base.json
+++ b/docs/translations/api-docs/input-base/input-base.json
@@ -5,6 +5,8 @@
"autoFocus": "If true
, the input
element is focused during the first mount.",
"classes": "Override or extend the styles applied to the component. See CSS API below for more details.",
"color": "The color of the component. It supports those theme colors that make sense for this component. The prop defaults to the value ('primary'
) inherited from the parent FormControl component.",
+ "components": "The components used for each slot inside the InputBase. Either a string to use a HTML element or a component.",
+ "componentsProps": "The props used for each slot inside the Input.",
"defaultValue": "The default value. Use when the component is not controlled.",
"disabled": "If true
, the component is disabled. The prop defaults to the value (false
) inherited from the parent FormControl component.",
"endAdornment": "End InputAdornment
for this component.",
diff --git a/packages/material-ui/src/Autocomplete/Autocomplete.js b/packages/material-ui/src/Autocomplete/Autocomplete.js
index d12e426b23f599..918afdaacd9620 100644
--- a/packages/material-ui/src/Autocomplete/Autocomplete.js
+++ b/packages/material-ui/src/Autocomplete/Autocomplete.js
@@ -102,7 +102,7 @@ export const styles = (theme) => ({
padding: '2.5px 4px',
},
},
- '&[class*="MuiFilledInput-root"]': {
+ '&.MuiFilledInput-root': {
paddingTop: 19,
paddingLeft: 8,
'$hasPopupIcon &, $hasClearIcon &': {
@@ -111,16 +111,16 @@ export const styles = (theme) => ({
'$hasPopupIcon$hasClearIcon &': {
paddingRight: 52 + 4 + 9,
},
- '& $input': {
+ '& .MuiFilledInput-input': {
padding: '7px 4px',
},
'& $endAdornment': {
right: 9,
},
},
- '&[class*="MuiFilledInput-root"][class*="MuiFilledInput-sizeSmall"]': {
+ '&.MuiFilledInput-root.MuiInputBase-sizeSmall': {
paddingBottom: 1,
- '& $input': {
+ '& .MuiFilledInput-input': {
padding: '2.5px 4px',
},
},
diff --git a/packages/material-ui/src/FilledInput/FilledInput.d.ts b/packages/material-ui/src/FilledInput/FilledInput.d.ts
index 16e5bf64fdc76a..16cb96ce162570 100644
--- a/packages/material-ui/src/FilledInput/FilledInput.d.ts
+++ b/packages/material-ui/src/FilledInput/FilledInput.d.ts
@@ -1,4 +1,5 @@
-import { InternalStandardProps as StandardProps } from '..';
+import { SxProps } from '@material-ui/system';
+import { InternalStandardProps as StandardProps, Theme } from '..';
import { InputBaseProps } from '../InputBase';
export interface FilledInputProps extends StandardProps {
@@ -45,6 +46,10 @@ export interface FilledInputProps extends StandardProps {
* If `true`, the input will not have an underline.
*/
disableUnderline?: boolean;
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx?: SxProps;
}
export type FilledInputClassKey = keyof NonNullable;
diff --git a/packages/material-ui/src/FilledInput/FilledInput.js b/packages/material-ui/src/FilledInput/FilledInput.js
index 733d542aa3f0d9..8d52f0914049d6 100644
--- a/packages/material-ui/src/FilledInput/FilledInput.js
+++ b/packages/material-ui/src/FilledInput/FilledInput.js
@@ -1,48 +1,67 @@
import * as React from 'react';
+import { deepmerge, refType } from '@material-ui/utils';
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 InputBase from '../InputBase';
-import withStyles from '../styles/withStyles';
+import experimentalStyled, { shouldForwardProp } from '../styles/experimentalStyled';
+import useThemeProps from '../styles/useThemeProps';
+import { getFilledInputUtilityClass } from './filledInputClasses';
+import {
+ overridesResolver as inputBaseOverridesResolver,
+ InputBaseRoot,
+ InputBaseComponent as InputBaseInput,
+} from '../InputBase/InputBase';
-export const styles = (theme) => {
+const overridesResolver = (props, styles) => {
+ const { styleProps } = props;
+ return deepmerge(inputBaseOverridesResolver(props, styles), {
+ ...(!styleProps.disableUnderline && styles.underline),
+ });
+};
+
+const useUtilityClasses = (styleProps) => {
+ const { classes, disableUnderline } = styleProps;
+
+ const slots = {
+ root: ['root', !disableUnderline && 'underline'],
+ input: ['input'],
+ };
+
+ return composeClasses(slots, getFilledInputUtilityClass, classes);
+};
+
+const FilledInputRoot = experimentalStyled(
+ InputBaseRoot,
+ { shouldForwardProp: (prop) => shouldForwardProp(prop) || prop === 'classes' },
+ { name: 'MuiFilledInput', slot: 'Root', overridesResolver },
+)(({ theme, styleProps }) => {
const light = theme.palette.mode === 'light';
const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)';
const backgroundColor = light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.09)';
-
return {
/* Styles applied to the root element. */
- root: {
- position: 'relative',
- backgroundColor,
- borderTopLeftRadius: theme.shape.borderRadius,
- borderTopRightRadius: theme.shape.borderRadius,
- transition: theme.transitions.create('background-color', {
- duration: theme.transitions.duration.shorter,
- easing: theme.transitions.easing.easeOut,
- }),
- '&:hover': {
- backgroundColor: light ? 'rgba(0, 0, 0, 0.13)' : 'rgba(255, 255, 255, 0.13)',
- // Reset on touch devices, it doesn't add specificity
- '@media (hover: none)': {
- backgroundColor,
- },
- },
- '&$focused': {
- backgroundColor: light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.09)',
- },
- '&$disabled': {
- backgroundColor: light ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.12)',
+ position: 'relative',
+ backgroundColor,
+ borderTopLeftRadius: theme.shape.borderRadius,
+ borderTopRightRadius: theme.shape.borderRadius,
+ transition: theme.transitions.create('background-color', {
+ duration: theme.transitions.duration.shorter,
+ easing: theme.transitions.easing.easeOut,
+ }),
+ '&:hover': {
+ backgroundColor: light ? 'rgba(0, 0, 0, 0.13)' : 'rgba(255, 255, 255, 0.13)',
+ // Reset on touch devices, it doesn't add specificity
+ '@media (hover: none)': {
+ backgroundColor,
},
},
- /* Styles applied to the root element if color secondary. */
- colorSecondary: {
- '&$underline:after': {
- borderBottomColor: theme.palette.secondary.main,
- },
+ '&.Mui-focused': {
+ backgroundColor: light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.09)',
+ },
+ '&.Mui-disabled': {
+ backgroundColor: light ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.12)',
},
- /* Styles applied to the root element unless `disableUnderline={true}`. */
- underline: {
+ ...(!styleProps.disableUnderline && {
'&:after': {
borderBottom: `2px solid ${theme.palette.primary.main}`,
left: 0,
@@ -57,11 +76,14 @@ export const styles = (theme) => {
easing: theme.transitions.easing.easeOut,
}),
pointerEvents: 'none', // Transparent to the hover style.
+ ...(styleProps.color === 'secondary' && {
+ borderBottomColor: theme.palette.secondary.main,
+ }),
},
- '&$focused:after': {
+ '&.Mui-focused:after': {
transform: 'scaleX(1)',
},
- '&$error:after': {
+ '&.Mui-error:after': {
borderBottomColor: theme.palette.error.main,
transform: 'scaleX(1)', // error is always underlined in red
},
@@ -78,87 +100,84 @@ export const styles = (theme) => {
}),
pointerEvents: 'none', // Transparent to the hover style.
},
- '&:hover:not($disabled):before': {
+ '&:hover:not(.Mui-disabled):before': {
borderBottom: `1px solid ${theme.palette.text.primary}`,
},
- '&$disabled:before': {
+ '&.Mui-disabled:before': {
borderBottomStyle: 'dotted',
},
- },
- /* Pseudo-class applied to the root element if the component is focused. */
- focused: {},
- /* Pseudo-class applied to the root element if `disabled={true}`. */
- disabled: {},
- /* Styles applied to the root element if `startAdornment` is provided. */
- adornedStart: {
+ }),
+ ...(styleProps.startAdornment && {
paddingLeft: 12,
- },
- /* Styles applied to the root element if `endAdornment` is provided. */
- adornedEnd: {
+ }),
+ ...(styleProps.endAdornment && {
paddingRight: 12,
- },
- /* Pseudo-class applied to the root element if `error={true}`. */
- error: {},
- /* Styles applied to the input element if `size="small"`. */
- sizeSmall: {},
- /* Styles applied to the root element if `multiline={true}`. */
- multiline: {
+ }),
+ ...(styleProps.multiline && {
padding: '25px 12px 8px',
- '&$sizeSmall': {
+ ...(styleProps.size === 'small' && {
paddingTop: 21,
paddingBottom: 4,
- },
- '&$hiddenLabel': {
+ }),
+ ...(styleProps.hiddenLabel && {
paddingTop: 16,
paddingBottom: 17,
- },
- },
- /* Styles applied to the root element if `hiddenLabel={true}`. */
- hiddenLabel: {},
- /* Styles applied to the input element. */
- input: {
- padding: '25px 12px 8px',
- '&:-webkit-autofill': {
- WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset',
- WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff',
- caretColor: theme.palette.mode === 'light' ? null : '#fff',
- borderTopLeftRadius: 'inherit',
- borderTopRightRadius: 'inherit',
- },
- },
- /* Styles applied to the input element if `size="small"`. */
- inputSizeSmall: {
- paddingTop: 21,
- paddingBottom: 4,
- },
- /* Styles applied to the `input` if in ``. */
- inputHiddenLabel: {
- paddingTop: 16,
- paddingBottom: 17,
- '&$inputSizeSmall': {
- paddingTop: 8,
- paddingBottom: 9,
- },
- },
- /* Styles applied to the input element if `multiline={true}`. */
- inputMultiline: {
- padding: 0,
- },
- /* Styles applied to the input element if `startAdornment` is provided. */
- inputAdornedStart: {
- paddingLeft: 0,
- },
- /* Styles applied to the input element if `endAdornment` is provided. */
- inputAdornedEnd: {
- paddingRight: 0,
- },
+ }),
+ }),
};
-};
+});
+
+const FilledInputInput = experimentalStyled(
+ InputBaseInput,
+ { shouldForwardProp: (prop) => shouldForwardProp(prop) || prop === 'classes' },
+ { name: 'MuiFilledInput', slot: 'Input' },
+)(({ theme, styleProps }) => ({
+ paddingTop: 25,
+ paddingRight: 12,
+ paddingBottom: 8,
+ paddingLeft: 12,
+ '&:-webkit-autofill': {
+ WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset',
+ WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff',
+ caretColor: theme.palette.mode === 'light' ? null : '#fff',
+ borderTopLeftRadius: 'inherit',
+ borderTopRightRadius: 'inherit',
+ },
+ ...(styleProps.size === 'small' && {
+ paddingTop: 21,
+ paddingBottom: 4,
+ }),
+ ...(styleProps.hiddenLabel && {
+ paddingTop: 16,
+ paddingBottom: 17,
+ }),
+ /* Styles applied to the input element if `multiline={true}`. */
+ ...(styleProps.multiline && {
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingLeft: 0,
+ paddingRight: 0,
+ }),
+ /* Styles applied to the input element if `startAdornment` is provided. */
+ ...(styleProps.startAdornment && {
+ paddingLeft: 0,
+ }),
+ /* Styles applied to the input element if `endAdornment` is provided. */
+ ...(styleProps.endAdornment && {
+ paddingRight: 0,
+ }),
+ ...(styleProps.hiddenLabel &&
+ styleProps.size === 'small' && {
+ paddingTop: 8,
+ paddingBottom: 9,
+ }),
+}));
+
+const FilledInput = React.forwardRef(function FilledInput(inProps, ref) {
+ const props = useThemeProps({ props: inProps, name: 'MuiFilledInput' });
-const FilledInput = React.forwardRef(function FilledInput(props, ref) {
const {
disableUnderline,
- classes,
fullWidth = false,
inputComponent = 'input',
multiline = false,
@@ -166,21 +185,27 @@ const FilledInput = React.forwardRef(function FilledInput(props, ref) {
...other
} = props;
+ const styleProps = {
+ ...props,
+ fullWidth,
+ inputComponent,
+ multiline,
+ type,
+ };
+
+ const classes = useUtilityClasses(props);
+
return (
);
});
@@ -307,6 +332,10 @@ FilledInput.propTypes = {
* Start `InputAdornment` for this component.
*/
startAdornment: PropTypes.node,
+ /**
+ * 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).
* @default 'text'
@@ -320,4 +349,4 @@ FilledInput.propTypes = {
FilledInput.muiName = 'Input';
-export default withStyles(styles, { name: 'MuiFilledInput' })(FilledInput);
+export default FilledInput;
diff --git a/packages/material-ui/src/FilledInput/FilledInput.test.js b/packages/material-ui/src/FilledInput/FilledInput.test.js
index 02003c8e7e578c..92282c4573ca86 100644
--- a/packages/material-ui/src/FilledInput/FilledInput.test.js
+++ b/packages/material-ui/src/FilledInput/FilledInput.test.js
@@ -1,24 +1,24 @@
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 FilledInput from './FilledInput';
import InputBase from '../InputBase';
+import classes from './filledInputClasses';
describe('', () => {
- let classes;
const mount = createMount();
const render = createClientRender();
- before(() => {
- classes = getClasses();
- });
-
- describeConformance(, () => ({
+ describeConformanceV5(, () => ({
classes,
inheritComponent: InputBase,
mount,
refInstanceof: window.HTMLDivElement,
- skip: ['componentProp'],
+ muiName: 'MuiFilledInput',
+ testDeepOverrides: { slotName: 'input', slotClassName: classes.input },
+ testVariantProps: { variant: 'contained', fullWidth: true },
+ testStateOverrides: { prop: 'size', value: 'small', styleKey: 'sizeSmall' },
+ skip: ['componentProp', 'componentsProp'],
}));
it('should have the underline class', () => {
diff --git a/packages/material-ui/src/FilledInput/filledInputClasses.d.ts b/packages/material-ui/src/FilledInput/filledInputClasses.d.ts
new file mode 100644
index 00000000000000..61979e72aa0d33
--- /dev/null
+++ b/packages/material-ui/src/FilledInput/filledInputClasses.d.ts
@@ -0,0 +1,11 @@
+export interface FilledInputClasses {
+ root: string;
+ underline: string;
+ input: string;
+}
+
+declare const filledInputClasses: FilledInputClasses;
+
+export function getFilledInputUtilityClass(slot: string): string;
+
+export default filledInputClasses;
diff --git a/packages/material-ui/src/FilledInput/filledInputClasses.js b/packages/material-ui/src/FilledInput/filledInputClasses.js
new file mode 100644
index 00000000000000..20b29a507dc290
--- /dev/null
+++ b/packages/material-ui/src/FilledInput/filledInputClasses.js
@@ -0,0 +1,9 @@
+import { generateUtilityClasses, generateUtilityClass } from '@material-ui/unstyled';
+
+export function getFilledInputUtilityClass(slot) {
+ return generateUtilityClass('MuiFilledInput', slot);
+}
+
+const filledInputClasses = generateUtilityClasses('MuiFilledInput', ['root', 'underline', 'input']);
+
+export default filledInputClasses;
diff --git a/packages/material-ui/src/FilledInput/index.d.ts b/packages/material-ui/src/FilledInput/index.d.ts
index fb808aeea4e9cd..f3576964636f51 100644
--- a/packages/material-ui/src/FilledInput/index.d.ts
+++ b/packages/material-ui/src/FilledInput/index.d.ts
@@ -1,2 +1,5 @@
export { default } from './FilledInput';
export * from './FilledInput';
+
+export { default as filledInputClasses } from './filledInputClasses';
+export * from './filledInputClasses';
diff --git a/packages/material-ui/src/FilledInput/index.js b/packages/material-ui/src/FilledInput/index.js
index 717577f9ee2552..91b5a314f0050b 100644
--- a/packages/material-ui/src/FilledInput/index.js
+++ b/packages/material-ui/src/FilledInput/index.js
@@ -1 +1,4 @@
export { default } from './FilledInput';
+
+export { default as filledInputClasses } from './filledInputClasses';
+export * from './filledInputClasses';
diff --git a/packages/material-ui/src/InputBase/InputBase.d.ts b/packages/material-ui/src/InputBase/InputBase.d.ts
index 1d0aa05ce59399..b4e8db3eac3483 100644
--- a/packages/material-ui/src/InputBase/InputBase.d.ts
+++ b/packages/material-ui/src/InputBase/InputBase.d.ts
@@ -72,6 +72,36 @@ export interface InputBaseProps
* The prop defaults to the value (`'primary'`) inherited from the parent FormControl component.
*/
color?: 'primary' | 'secondary';
+ /**
+ * The components used for each slot inside the InputBase.
+ * Either a string to use a HTML element or a component.
+ * @default {}
+ */
+ components?: {
+ Root?: React.ElementType;
+ Input?: React.ElementType;
+ };
+
+ /**
+ * The props used for each slot inside the Input.
+ * @default {}
+ */
+ componentsProps?: {
+ root?: {
+ as: React.ElementType;
+ styleProps?: Omit & {
+ hiddenLabel?: boolean;
+ focused?: boolean;
+ };
+ };
+ input?: {
+ as?: React.ElementType;
+ styleProps?: Omit & {
+ hiddenLabel?: boolean;
+ focused?: boolean;
+ };
+ };
+ };
/**
* The default value. Use when the component is not controlled.
*/
diff --git a/packages/material-ui/src/InputBase/InputBase.js b/packages/material-ui/src/InputBase/InputBase.js
index 31caf600980e1a..fdfb67001be8a0 100644
--- a/packages/material-ui/src/InputBase/InputBase.js
+++ b/packages/material-ui/src/InputBase/InputBase.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import clsx from 'clsx';
import { refType, elementTypeAcceptingRef, deepmerge } from '@material-ui/utils';
import MuiError from '@material-ui/utils/macros/MuiError.macro';
-import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
+import { unstable_composeClasses as composeClasses, isHostComponent } from '@material-ui/unstyled';
import formControlState from '../FormControl/formControlState';
import FormControlContext, { useFormControl } from '../FormControl/FormControlContext';
import experimentalStyled, { shouldForwardProp } from '../styles/experimentalStyled';
@@ -16,7 +16,7 @@ import GlobalStyles from '../GlobalStyles';
import { isFilled } from './utils';
import inputBaseClasses, { getInputBaseUtilityClass } from './inputBaseClasses';
-const overridesResolver = (props, styles) => {
+export const overridesResolver = (props, styles) => {
const { styleProps } = props;
return deepmerge(styles.root || {}, {
@@ -87,7 +87,7 @@ const useUtilityClasses = (styleProps) => {
return composeClasses(slots, getInputBaseUtilityClass, classes);
};
-const InputBaseRoot = experimentalStyled(
+export const InputBaseRoot = experimentalStyled(
'div',
{},
{
@@ -119,7 +119,7 @@ const InputBaseRoot = experimentalStyled(
}),
}));
-const InputBaseComponent = experimentalStyled(
+export const InputBaseComponent = experimentalStyled(
'input',
{ shouldForwardProp: (prop) => shouldForwardProp(prop) || prop === 'classes' },
{
@@ -225,6 +225,8 @@ const InputBase = React.forwardRef(function InputBase(inProps, ref) {
autoFocus,
className,
color,
+ components = {},
+ componentsProps = {},
defaultValue,
disabled,
endAdornment,
@@ -253,6 +255,10 @@ const InputBase = React.forwardRef(function InputBase(inProps, ref) {
startAdornment,
type = 'text',
value: valueProp,
+ /* eslint-disable-next-line react/prop-types */
+ isRtl,
+ /* eslint-disable-next-line react/prop-types */
+ theme,
...other
} = props;
@@ -471,6 +477,12 @@ const InputBase = React.forwardRef(function InputBase(inProps, ref) {
const classes = useUtilityClasses(styleProps);
+ const Root = components.Root || InputBaseRoot;
+ const rootProps = componentsProps.root || {};
+
+ const Input = components.Input || InputBaseComponent;
+ inputProps = { ...inputProps, ...componentsProps.input };
+
return (
-
{startAdornment}
-
+
);
});
@@ -560,6 +580,20 @@ InputBase.propTypes = {
* The prop defaults to the value (`'primary'`) inherited from the parent FormControl component.
*/
color: PropTypes.oneOf(['primary', 'secondary']),
+ /**
+ * The components used for each slot inside the InputBase.
+ * Either a string to use a HTML element or a component.
+ * @default {}
+ */
+ components: PropTypes.shape({
+ Input: PropTypes.elementType,
+ Root: PropTypes.elementType,
+ }),
+ /**
+ * The props used for each slot inside the Input.
+ * @default {}
+ */
+ componentsProps: PropTypes.object,
/**
* The default value. Use when the component is not controlled.
*/
diff --git a/packages/material-ui/src/InputBase/InputBase.test.js b/packages/material-ui/src/InputBase/InputBase.test.js
index 8d9e69d7e99ea8..e0dc33f39eba36 100644
--- a/packages/material-ui/src/InputBase/InputBase.test.js
+++ b/packages/material-ui/src/InputBase/InputBase.test.js
@@ -21,7 +21,7 @@ describe('', () => {
refInstanceof: window.HTMLDivElement,
muiName: 'MuiInputBase',
testVariantProps: { size: 'small' },
- skip: ['componentProp', 'componentsProp'],
+ skip: ['componentProp'],
}));
it('should render an inside the div', () => {