diff --git a/docs/src/pages/demos/autocomplete/IntegrationReactSelect.js b/docs/src/pages/demos/autocomplete/IntegrationReactSelect.js index d2c680a71f32eb..de42f84f61643c 100644 --- a/docs/src/pages/demos/autocomplete/IntegrationReactSelect.js +++ b/docs/src/pages/demos/autocomplete/IntegrationReactSelect.js @@ -123,14 +123,14 @@ function Control(props) { fullWidth InputProps={{ inputComponent, - inputProps: { - className: props.selectProps.classes.input, - inputRef: props.innerRef, - children: props.children, - ...props.innerProps, + inputRef: props.innerRef, + children: props.children, + classes: { + input: props.selectProps.classes.input, }, + ...props.innerProps, }} - {...props.selectProps.textFieldProps} + {...props.selectProps.TextFieldProps} /> ); } @@ -248,7 +248,7 @@ function IntegrationReactSelect() { false xs diff --git a/docs/src/pages/demos/pickers/TimePickers.js b/docs/src/pages/demos/pickers/TimePickers.js index 0ba9e697165fb1..566d26fde569f8 100644 --- a/docs/src/pages/demos/pickers/TimePickers.js +++ b/docs/src/pages/demos/pickers/TimePickers.js @@ -29,7 +29,7 @@ function TimePickers(props) { InputLabelProps={{ shrink: true, }} - inputProps={{ + InputProps={{ step: 300, // 5 min }} /> diff --git a/docs/src/pages/demos/selects/ControlledOpenSelect.js b/docs/src/pages/demos/selects/ControlledOpenSelect.js index d696b34d6eabb9..ebe1c5b7062a98 100644 --- a/docs/src/pages/demos/selects/ControlledOpenSelect.js +++ b/docs/src/pages/demos/selects/ControlledOpenSelect.js @@ -47,10 +47,8 @@ function ControlledOpenSelect() { onOpen={handleOpen} value={age} onChange={handleChange} - inputProps={{ - name: 'age', - id: 'demo-controlled-open-select', - }} + name="age" + id="demo-controlled-open-select" > None diff --git a/docs/src/pages/demos/selects/MultipleSelect.js b/docs/src/pages/demos/selects/MultipleSelect.js index dea568fe75932b..75dd40f35c4ac2 100644 --- a/docs/src/pages/demos/selects/MultipleSelect.js +++ b/docs/src/pages/demos/selects/MultipleSelect.js @@ -179,9 +179,7 @@ function MultipleSelect() { native value={personName} onChange={handleChangeMultiple} - inputProps={{ - id: 'select-multiple-native', - }} + id="select-multiple-native" > {names.map(name => ( @@ -176,9 +174,7 @@ function NativeSelects() { value={state.age} onChange={handleChange('age')} name="age" - inputProps={{ - id: 'age-native-required', - }} + id="age-native-required" > diff --git a/docs/src/pages/demos/selects/SimpleSelect.js b/docs/src/pages/demos/selects/SimpleSelect.js index aa88b6cf692583..0769dca6716b31 100644 --- a/docs/src/pages/demos/selects/SimpleSelect.js +++ b/docs/src/pages/demos/selects/SimpleSelect.js @@ -47,14 +47,7 @@ function SimpleSelect() {
Age - None @@ -207,9 +200,7 @@ function SimpleSelect() { value={values.age} onChange={handleChange} name="age" - inputProps={{ - id: 'age-required', - }} + id="age-required" className={classes.selectEmpty} > diff --git a/docs/src/pages/demos/text-fields/InputAdornments.js b/docs/src/pages/demos/text-fields/InputAdornments.js index 9c0d54dd697f3b..2161b362427660 100644 --- a/docs/src/pages/demos/text-fields/InputAdornments.js +++ b/docs/src/pages/demos/text-fields/InputAdornments.js @@ -103,9 +103,7 @@ function InputAdornments() { onChange={handleChange('weight')} endAdornment={Kg} aria-describedby="weight-helper-text" - inputProps={{ - 'aria-label': 'Weight', - }} + aria-label="Weight" /> Weight diff --git a/docs/src/pages/demos/text-fields/InputAdornments.tsx b/docs/src/pages/demos/text-fields/InputAdornments.tsx index 893a10ee2f66ff..dd4b478fe604ec 100644 --- a/docs/src/pages/demos/text-fields/InputAdornments.tsx +++ b/docs/src/pages/demos/text-fields/InputAdornments.tsx @@ -107,9 +107,7 @@ function InputAdornments() { onChange={handleChange('weight')} endAdornment={Kg} aria-describedby="weight-helper-text" - inputProps={{ - 'aria-label': 'Weight', - }} + aria-label="Weight" /> Weight diff --git a/docs/src/pages/demos/text-fields/Inputs.js b/docs/src/pages/demos/text-fields/Inputs.js index bbc3f44e44d36b..c9608c29f4ae59 100644 --- a/docs/src/pages/demos/text-fields/Inputs.js +++ b/docs/src/pages/demos/text-fields/Inputs.js @@ -17,36 +17,10 @@ function Inputs(props) { const { classes } = props; return (
- - - - + + + +
); } diff --git a/docs/src/pages/demos/text-fields/Inputs.tsx b/docs/src/pages/demos/text-fields/Inputs.tsx index 77e5a9ef4935c9..25d9f77e60e1c2 100644 --- a/docs/src/pages/demos/text-fields/Inputs.tsx +++ b/docs/src/pages/demos/text-fields/Inputs.tsx @@ -20,36 +20,10 @@ function Inputs(props: Props) { const { classes } = props; return (
- - - - + + + +
); } diff --git a/docs/src/pages/demos/text-fields/text-fields.md b/docs/src/pages/demos/text-fields/text-fields.md index 8a02f541130328..ff768491c8cc65 100644 --- a/docs/src/pages/demos/text-fields/text-fields.md +++ b/docs/src/pages/demos/text-fields/text-fields.md @@ -40,9 +40,9 @@ The `TextField` wrapper component is a complete form control including a label, and [`FormHelperText`](/api/form-helper-text/) ) that you can leverage directly to significantly customize your form inputs. -You might also have noticed that some native HTML input properties are missing from the `TextField` component. +You might also have noticed that some properties are missing from the `TextField` component. This is on purpose. -The component takes care of the most used properties, then it's up to the user to use the underlying component shown in the following demo. Still, you can use `inputProps` (and `InputProps`, `InputLabelProps` properties) if you want to avoid some boilerplate. +The component takes care of the most used properties, then it's up to the user to use the underlying component shown in the following demo. Still, you can use the `FormHelperTextProps`, `InputLabel` and `SelectProps` properties if you want to avoid some boilerplate. {{"demo": "pages/demos/text-fields/ComposedTextField.js"}} diff --git a/docs/src/pages/discover-more/showcase/Showcase.js b/docs/src/pages/discover-more/showcase/Showcase.js index afc9af61f6bc6e..aacc26f411029f 100644 --- a/docs/src/pages/discover-more/showcase/Showcase.js +++ b/docs/src/pages/discover-more/showcase/Showcase.js @@ -87,7 +87,7 @@ function Showcase(props) {
Sort by - {t('newest')} {t('traffic')} {t('stars')} diff --git a/docs/src/pages/guides/api/api.md b/docs/src/pages/guides/api/api.md index 56205a8014e143..9b02bcbe82b0be 100644 --- a/docs/src/pages/guides/api/api.md +++ b/docs/src/pages/guides/api/api.md @@ -77,7 +77,7 @@ Nested components inside a component have: - their own flattened properties when these are key to the top level component abstraction, for instance and `id` property for the `Input` component. - their own `xxxProps` property when users might need to tweak the internal render method's sub-components, - for instance, exposing the `inputProps` and `InputProps` properties on components that use `Input` internally. + for instance, exposing the `InputProps` property on components that use `Input` internally. - their own `xxxComponent` property for performing component injection. - their own `xxxRef` property when user might need to perform imperative actions, for instance, exposing a `inputRef` property to access the native `input` on the `Input` component. diff --git a/docs/src/pages/premium-themes/onepirate/modules/form/RFTextField.js b/docs/src/pages/premium-themes/onepirate/modules/form/RFTextField.js index c8ed7043800241..720dafc7cc935d 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/form/RFTextField.js +++ b/docs/src/pages/premium-themes/onepirate/modules/form/RFTextField.js @@ -17,9 +17,7 @@ function RFTextField(props) { {...input} {...other} InputProps={{ - inputProps: { - autoComplete, - }, + autoComplete, ...InputProps, }} helperText={touched ? error || submitError : ''} diff --git a/docs/src/pages/style/color/ColorTool.js b/docs/src/pages/style/color/ColorTool.js index dc06693bf63150..6dde5748003d01 100644 --- a/docs/src/pages/style/color/ColorTool.js +++ b/docs/src/pages/style/color/ColorTool.js @@ -193,9 +193,7 @@ class ColorTool extends React.Component { id={intent} value={intentInput} onChange={this.handleChangeColor(intent)} - inputProps={{ - 'aria-label': `${capitalize(intent)} color`, - }} + aria-label={`${capitalize(intent)} color`} fullWidth />
diff --git a/packages/material-ui/src/InputBase/InputBase.js b/packages/material-ui/src/InputBase/InputBase.js index a8880796cf0014..03bcfcf40b8de4 100644 --- a/packages/material-ui/src/InputBase/InputBase.js +++ b/packages/material-ui/src/InputBase/InputBase.js @@ -36,6 +36,7 @@ export const styles = theme => { fontFamily: theme.typography.fontFamily, color: theme.palette.text.primary, fontSize: theme.typography.pxToRem(16), + position: 'relative', lineHeight: '1.1875em', // Reset (19px), match the native input line-height boxSizing: 'border-box', // Prevent padding issue with fullWidth. cursor: 'text', @@ -284,11 +285,8 @@ class InputBase extends React.Component { render() { const { - autoComplete, - autoFocus, classes, - className: classNameProp, - defaultValue, + className, disabled, endAdornment, error, @@ -301,17 +299,12 @@ class InputBase extends React.Component { margin, muiFormControl, multiline, - name, onBlur, onChange, onClick, onEmpty, onFilled, onFocus, - onKeyDown, - onKeyUp, - placeholder, - readOnly, renderPrefix, rows, rowsMax, @@ -321,9 +314,6 @@ class InputBase extends React.Component { ...other } = this.props; - const ariaDescribedby = other['aria-describedby']; - delete other['aria-describedby']; - const fcs = formControlState({ props: this.props, muiFormControl, @@ -332,36 +322,6 @@ class InputBase extends React.Component { const focused = muiFormControl ? muiFormControl.focused : this.state.focused; - const className = clsx( - classes.root, - { - [classes.disabled]: fcs.disabled, - [classes.error]: fcs.error, - [classes.fullWidth]: fullWidth, - [classes.focused]: focused, - [classes.formControl]: muiFormControl, - [classes.marginDense]: fcs.margin === 'dense', - [classes.multiline]: multiline, - [classes.adornedStart]: startAdornment, - [classes.adornedEnd]: endAdornment, - }, - classNameProp, - ); - - const inputClassName = clsx( - classes.input, - { - [classes.disabled]: fcs.disabled, - [classes.inputType]: type !== 'text', - [classes.inputTypeSearch]: type === 'search', - [classes.inputMultiline]: multiline, - [classes.inputMarginDense]: fcs.margin === 'dense', - [classes.inputAdornedStart]: startAdornment, - [classes.inputAdornedEnd]: endAdornment, - }, - inputPropsClassName, - ); - let InputComponent = inputComponent; let inputProps = { ...inputPropsProp, @@ -397,7 +357,25 @@ class InputBase extends React.Component { } return ( -
+
{renderPrefix ? renderPrefix({ ...fcs, @@ -409,24 +387,28 @@ class InputBase extends React.Component { @@ -552,14 +534,6 @@ InputBase.propTypes = { * @ignore */ onFocus: PropTypes.func, - /** - * @ignore - */ - onKeyDown: PropTypes.func, - /** - * @ignore - */ - onKeyUp: PropTypes.func, /** * The short hint displayed in the input before the user enters a value. */ diff --git a/packages/material-ui/src/InputBase/InputBase.test.js b/packages/material-ui/src/InputBase/InputBase.test.js index 1a0076f60d30e9..7299a001c637cc 100644 --- a/packages/material-ui/src/InputBase/InputBase.test.js +++ b/packages/material-ui/src/InputBase/InputBase.test.js @@ -38,6 +38,7 @@ describe('', () => { classes, inheritComponent: 'div', mount, + propsSpread: false, refInstanceof: window.HTMLDivElement, testComponentPropWith: false, })); @@ -515,6 +516,18 @@ describe('', () => { }); }); + it('should pass aria attributes to input', () => { + const ariaAttributes = { + 'aria-autocomplete': 'list', + 'aria-controls': 'menu', + 'aria-labelledby': 'label', + }; + const wrapper = mount(); + + assert.include(wrapper.find('input').props(), ariaAttributes); + assert.notInclude(wrapper.find('div').props(), ariaAttributes); + }); + describe('prop: inputRef', () => { it('should be able to return the input node via a ref object', () => { const ref = React.createRef(); diff --git a/packages/material-ui/src/NativeSelect/NativeSelect.js b/packages/material-ui/src/NativeSelect/NativeSelect.js index bce1fc020142f5..d686d9e2526a71 100644 --- a/packages/material-ui/src/NativeSelect/NativeSelect.js +++ b/packages/material-ui/src/NativeSelect/NativeSelect.js @@ -10,12 +10,7 @@ import ArrowDropDownIcon from '../internal/svg-icons/ArrowDropDown'; import Input from '../Input'; export const styles = theme => ({ - /* Styles applied to the `Input` component `root` class. */ - root: { - position: 'relative', - width: '100%', - }, - /* Styles applied to the `Input` component `select` class. */ + /* Styles applied to the select component `select` class. */ select: { '-moz-appearance': 'none', // Reset '-webkit-appearance': 'none', // Reset @@ -25,7 +20,6 @@ export const styles = theme => ({ paddingRight: 32, borderRadius: 0, // Reset height: '1.1875em', // Reset (19px), match the native input line-height - width: 'calc(100% - 32px)', minWidth: 16, // So it doesn't collapse. cursor: 'pointer', '&:focus': { @@ -48,27 +42,23 @@ export const styles = theme => ({ backgroundColor: theme.palette.background.paper, }, }, - /* Styles applied to the `Input` component if `variant="filled"`. */ - filled: { - width: 'calc(100% - 44px)', - }, - /* Styles applied to the `Input` component if `variant="outlined"`. */ + /* Styles applied to the select component if `variant="filled"`. */ + filled: {}, + /* Styles applied to the select component if `variant="outlined"`. */ outlined: { - width: 'calc(100% - 46px)', borderRadius: theme.shape.borderRadius, }, - /* Styles applied to the `Input` component `selectMenu` class. */ + /* Styles applied to the select component `selectMenu` class. */ selectMenu: { - width: 'auto', // Fix Safari textOverflow - height: 'auto', // Reset textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden', + height: 'auto', minHeight: '1.1875em', // Reset (19px), match the native input line-height }, - /* Styles applied to the `Input` component `disabled` class. */ + /* Styles applied to the select component `disabled` class. */ disabled: {}, - /* Styles applied to the `Input` component `icon` class. */ + /* Styles applied to the select component `icon` class. */ icon: { // We use a position absolute over a flexbox in order to forward the pointer events // to the input. @@ -104,13 +94,13 @@ const NativeSelect = React.forwardRef(function NativeSelect(props, ref) { // Most of the logic is implemented in `NativeSelectInput`. // The `Select` component is a simple API wrapper to expose something better to play with. inputComponent: NativeSelectInput, + children, + IconComponent, + variant: fcs.variant, + type: 'hidden', // We render a select. We can ignore the type provided by the `Input`. inputProps: { - children, - classes, - IconComponent, - variant: fcs.variant, - type: undefined, // We render a select. We can ignore the type provided by the `Input`. ...inputProps, + classes, ...(input ? input.props.inputProps : {}), }, ref, diff --git a/packages/material-ui/src/NativeSelect/NativeSelectInput.js b/packages/material-ui/src/NativeSelect/NativeSelectInput.js index d47064134fbaa9..ca7e8aa8c44fb4 100644 --- a/packages/material-ui/src/NativeSelect/NativeSelectInput.js +++ b/packages/material-ui/src/NativeSelect/NativeSelectInput.js @@ -13,15 +13,12 @@ const NativeSelectInput = React.forwardRef(function NativeSelectInput(props, ref disabled, IconComponent, inputRef, - name, - onChange, - value, variant, ...other } = props; return ( -
+ -
+ ); }); diff --git a/packages/material-ui/src/Select/Select.js b/packages/material-ui/src/Select/Select.js index 2a55d11e2195ab..f8cf2614ed2259 100644 --- a/packages/material-ui/src/Select/Select.js +++ b/packages/material-ui/src/Select/Select.js @@ -48,24 +48,24 @@ const Select = React.forwardRef(function Select(props, ref) { // Most of the logic is implemented in `SelectInput`. // The `Select` component is a simple API wrapper to expose something better to play with. inputComponent, + children, + IconComponent, + variant: fcs.variant, + type: 'hidden', // We render a select. We can ignore the type provided by the `Input`. + multiple, + ...(native + ? {} + : { + autoWidth, + displayEmpty, + MenuProps, + onClose, + onOpen, + open, + renderValue, + SelectDisplayProps, + }), inputProps: { - children, - IconComponent, - variant: fcs.variant, - type: undefined, // We render a select. We can ignore the type provided by the `Input`. - multiple, - ...(native - ? {} - : { - autoWidth, - displayEmpty, - MenuProps, - onClose, - onOpen, - open, - renderValue, - SelectDisplayProps, - }), ...inputProps, classes: inputProps ? mergeClasses({ diff --git a/packages/material-ui/src/Select/Select.test.js b/packages/material-ui/src/Select/Select.test.js index dbea6e46cd0584..9f40ba247db8fb 100644 --- a/packages/material-ui/src/Select/Select.test.js +++ b/packages/material-ui/src/Select/Select.test.js @@ -47,13 +47,13 @@ describe(', ); assert.deepEqual(wrapper.find(Input).props().inputProps.classes, { ...classes, - root: `${classes.root} root`, + select: `${classes.select} select`, }); }); }); diff --git a/packages/material-ui/src/Select/SelectInput.js b/packages/material-ui/src/Select/SelectInput.js index ed0e9b108f0915..30fe0ffb2d8334 100644 --- a/packages/material-ui/src/Select/SelectInput.js +++ b/packages/material-ui/src/Select/SelectInput.js @@ -195,15 +195,14 @@ class SelectInput extends React.Component { required, SelectDisplayProps, tabIndex: tabIndexProp, - type = 'hidden', value, variant, ...other } = this.props; - const open = this.isOpenControlled && this.displayRef ? openProp : this.state.open; - delete other['aria-invalid']; + const open = this.isOpenControlled && this.displayRef ? openProp : this.state.open; + let display; let displaySingle = ''; const displayMultiple = []; @@ -280,7 +279,7 @@ class SelectInput extends React.Component { } return ( -
+
@@ -340,7 +338,7 @@ class SelectInput extends React.Component { > {items} -
+
); } } @@ -457,7 +455,7 @@ SelectInput.propTypes = { /** * @ignore */ - type: PropTypes.string, + type: PropTypes.string.isRequired, /** * The input value. */ diff --git a/packages/material-ui/src/Select/SelectInput.test.js b/packages/material-ui/src/Select/SelectInput.test.js index a1ec87fc76036b..c491f4d5f0fe86 100644 --- a/packages/material-ui/src/Select/SelectInput.test.js +++ b/packages/material-ui/src/Select/SelectInput.test.js @@ -12,6 +12,7 @@ describe('', () => { let mount; const defaultProps = { classes: { select: 'select' }, + type: 'hidden', autoWidth: false, value: 10, multiple: false, @@ -41,7 +42,7 @@ describe('', () => { it('should render a correct top element', () => { const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'div'); + assert.strictEqual(wrapper.name(), 'Fragment'); assert.strictEqual( wrapper .find(MenuItem) @@ -129,15 +130,10 @@ describe('', () => { }); describe('prop: type', () => { - it('should be hidden by default', () => { - const wrapper = shallow(); + it('should forward the prop', () => { + const wrapper = shallow(); assert.strictEqual(wrapper.find('input').props().type, 'hidden'); }); - - it('should be able to override it', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.find('input').props().type, 'text'); - }); }); describe('prop: displayEmpty', () => { diff --git a/packages/material-ui/src/TablePagination/TablePagination.js b/packages/material-ui/src/TablePagination/TablePagination.js index de6268030e81e3..701e4781117263 100644 --- a/packages/material-ui/src/TablePagination/TablePagination.js +++ b/packages/material-ui/src/TablePagination/TablePagination.js @@ -36,11 +36,6 @@ export const styles = theme => ({ caption: { flexShrink: 0, }, - /* Styles applied to the Select component `root` class. */ - selectRoot: { - marginRight: 32, - marginLeft: 8, - }, /* Styles applied to the Select component `select` class. */ select: { paddingLeft: 8, @@ -54,6 +49,8 @@ export const styles = theme => ({ }, /* Styles applied to the `InputBase` component. */ input: { + marginRight: 32, + marginLeft: 8, color: 'inherit', fontSize: 'inherit', flexShrink: 0, @@ -110,7 +107,6 @@ const TablePagination = React.forwardRef(function TablePagination(props, ref) { {rowsPerPageOptions.length > 1 && ( +