From d07255011ecb2290d072e50ce8d64f61791e45bb Mon Sep 17 00:00:00 2001 From: joshwooding <12938082+joshwooding@users.noreply.github.com> Date: Fri, 28 Dec 2018 01:49:44 +0000 Subject: [PATCH 1/2] Automatically inherit the InputAdornment variant --- .../src/InputAdornment/InputAdornment.js | 29 +++- .../src/InputAdornment/InputAdornment.test.js | 154 ++++++++++++++---- .../material-ui/src/InputBase/InputBase.js | 3 +- pages/api/input-adornment.md | 2 +- 4 files changed, 156 insertions(+), 32 deletions(-) diff --git a/packages/material-ui/src/InputAdornment/InputAdornment.js b/packages/material-ui/src/InputAdornment/InputAdornment.js index 6c95db69d660db..52493e3b08096f 100644 --- a/packages/material-ui/src/InputAdornment/InputAdornment.js +++ b/packages/material-ui/src/InputAdornment/InputAdornment.js @@ -2,8 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { componentPropType } from '@material-ui/utils'; +import warning from 'warning'; import Typography from '../Typography'; import withStyles from '../styles/withStyles'; +import withFormControlContext from '../FormControl/withFormControlContext'; export const styles = { /* Styles applied to the root element. */ @@ -41,11 +43,26 @@ function InputAdornment(props) { className, disablePointerEvents, disableTypography, + muiFormControl, position, - variant, + variant: variantProp, ...other } = props; + let variant = variantProp; + + if (variantProp && muiFormControl) { + warning( + variantProp !== muiFormControl.variant, + 'Material-UI: The `InputAdornment` variant infers the variant property ' + + 'you do not have to provide one.', + ); + } + + if (muiFormControl && !variant) { + variant = muiFormControl.variant; + } + return ( ', () => { - let shallow; + let mount; let classes; before(() => { - shallow = createShallow({ dive: true }); + mount = createMount(); classes = getClasses(foo); }); + after(() => { + mount.cleanUp(); + }); + it('should render a div', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(foo); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.name(), 'div'); }); it('should render given component', () => { - const wrapper = shallow( + const wrapper = mount( foo , ); - assert.strictEqual(wrapper.name(), 'span'); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.name(), 'span'); }); it('should wrap text children in a Typography', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.childAt(0).type(), Typography); + const wrapper = mount(foo); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.childAt(0).type(), Typography); }); it('should have the root and start class when position is start', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.positionStart), true); + const wrapper = mount(foo); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionStart), true); }); it('should have the root and end class when position is end', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.positionEnd), true); + const wrapper = mount(foo); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionEnd), true); }); - it('should have the filled root and class when variant is filled', () => { - const wrapper = shallow( - - foo - , - ); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.positionStart), true); - assert.strictEqual(wrapper.hasClass(classes.filled), true); + describe('prop: variant', () => { + it("should inherit the TextField's variant", () => { + const wrapper = mount( + foo }} + />, + ); + const adornment = findOutermostIntrinsic(wrapper.find(InputAdornment)); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionStart), true); + assert.strictEqual(adornment.hasClass(classes.filled), true); + }); + + it("should inherit the FormControl's variant", () => { + const wrapper = mount( + + foo} /> + , + ); + const adornment = findOutermostIntrinsic(wrapper.find(InputAdornment)); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionStart), true); + assert.strictEqual(adornment.hasClass(classes.filled), true); + }); + + it('should override the inherited variant', () => { + const wrapper = mount( + + foo + + ), + }} + />, + ); + const adornment = findOutermostIntrinsic(wrapper.find(InputAdornment)); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionStart), true); + assert.strictEqual(adornment.hasClass(classes.filled), false); + }); + + it('should have the filled root and class when variant is filled', () => { + const wrapper = mount( + + foo + , + ); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.hasClass(classes.root), true); + assert.strictEqual(adornment.hasClass(classes.positionStart), true); + assert.strictEqual(adornment.hasClass(classes.filled), true); + }); + + describe('warnings', () => { + before(() => { + consoleErrorMock.spy(); + }); + + after(() => { + consoleErrorMock.reset(); + }); + + it('should warn if the variant supplied is equal to the variant inferred', () => { + mount( + + + foo + + } + /> + , + ); + assert.strictEqual(consoleErrorMock.callCount(), 1); + assert.strictEqual( + consoleErrorMock.args()[0][0], + 'Warning: Material-UI: The `InputAdornment` variant infers the variant ' + + 'property you do not have to provide one.', + ); + }); + }); }); it('should have the disabled pointer events class when disabledPointerEvents true', () => { @@ -65,20 +161,22 @@ describe('', () => { }); it('should not wrap text children in a Typography when disableTypography true', () => { - const wrapper = shallow( + const wrapper = mount( foo , ); - assert.strictEqual(wrapper.childAt(0).text(), 'foo'); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.text(), 'foo'); }); it('should render children', () => { - const wrapper = shallow( + const wrapper = mount(
foo
, ); - assert.strictEqual(wrapper.childAt(0).name(), 'div'); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.childAt(0).name(), 'div'); }); }); diff --git a/packages/material-ui/src/InputBase/InputBase.js b/packages/material-ui/src/InputBase/InputBase.js index 96426cfe5fb181..6aa3173c86dde3 100644 --- a/packages/material-ui/src/InputBase/InputBase.js +++ b/packages/material-ui/src/InputBase/InputBase.js @@ -326,6 +326,7 @@ class InputBase extends React.Component { }); const focused = muiFormControl ? muiFormControl.focused : this.state.focused; + const variantContext = muiFormControl ? muiFormControl.variant : null; const className = classNames( classes.root, @@ -392,7 +393,7 @@ class InputBase extends React.Component { } return ( - +
{renderPrefix ? renderPrefix({ diff --git a/pages/api/input-adornment.md b/pages/api/input-adornment.md index aaa8273f37940f..5841e3a1a1c1a3 100644 --- a/pages/api/input-adornment.md +++ b/pages/api/input-adornment.md @@ -24,7 +24,7 @@ import InputAdornment from '@material-ui/core/InputAdornment'; | disablePointerEvents | bool | false | Disable pointer events on the root. This allows for the content of the adornment to focus the input on click. | | disableTypography | bool | false | If children is a string then disable wrapping in a Typography component. | | position | enum: 'start' |
 'end'
|   | The position this adornment should appear relative to the `Input`. | -| variant | enum: 'standard' |
 'outlined' |
 'filled'
|   | The variant to use. | +| variant | enum: 'standard' |
 'outlined' |
 'filled'
|   | The variant to use. Note: If you are using the `TextField` component or the `FormControl` component you do not have to set this manually. | Any other properties supplied will be spread to the root element (native element). From d7ef9b0a8b4563918f144add831b4e04e2fef899 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Fri, 18 Jan 2019 00:43:42 +0100 Subject: [PATCH 2/2] let's merge --- .size-limit.js | 2 +- .../FilledInputAdornments.hooks.js | 26 ++++-------------- .../text-fields/FilledInputAdornments.js | 26 ++++-------------- .../text-fields/FormattedInputs.hooks.js | 4 ++- .../src/InputAdornment/InputAdornment.test.js | 5 ++-- .../material-ui/src/InputBase/InputBase.js | 27 +++++++++---------- 6 files changed, 30 insertions(+), 60 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index debbadfef2e5f6..1877bebe45dc66 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -22,7 +22,7 @@ module.exports = [ name: 'The size of the @material-ui/core modules', webpack: true, path: 'packages/material-ui/build/index.js', - limit: '95.2 KB', + limit: '95.3 KB', }, { name: 'The size of the @material-ui/styles modules', diff --git a/docs/src/pages/demos/text-fields/FilledInputAdornments.hooks.js b/docs/src/pages/demos/text-fields/FilledInputAdornments.hooks.js index f9ed96a180c692..bc28f0ca8c022c 100644 --- a/docs/src/pages/demos/text-fields/FilledInputAdornments.hooks.js +++ b/docs/src/pages/demos/text-fields/FilledInputAdornments.hooks.js @@ -62,11 +62,7 @@ function FilledInputAdornments() { variant="filled" label="With filled TextField" InputProps={{ - startAdornment: ( - - Kg - - ), + startAdornment: Kg, }} /> - Kg - - ), + startAdornment: Kg, }} > {ranges.map(option => ( @@ -98,11 +90,7 @@ function FilledInputAdornments() { value={values.amount} onChange={handleChange('amount')} InputProps={{ - startAdornment: ( - - $ - - ), + startAdornment: $, }} /> - Kg - - ), + endAdornment: Kg, }} /> + {values.showPassword ? : } diff --git a/docs/src/pages/demos/text-fields/FilledInputAdornments.js b/docs/src/pages/demos/text-fields/FilledInputAdornments.js index 96b9234268f959..b2b6a59a0308db 100644 --- a/docs/src/pages/demos/text-fields/FilledInputAdornments.js +++ b/docs/src/pages/demos/text-fields/FilledInputAdornments.js @@ -65,11 +65,7 @@ class FilledInputAdornments extends React.Component { variant="filled" label="With filled TextField" InputProps={{ - startAdornment: ( - - Kg - - ), + startAdornment: Kg, }} /> - Kg - - ), + startAdornment: Kg, }} > {ranges.map(option => ( @@ -101,11 +93,7 @@ class FilledInputAdornments extends React.Component { value={this.state.amount} onChange={this.handleChange('amount')} InputProps={{ - startAdornment: ( - - $ - - ), + startAdornment: $, }} /> - Kg - - ), + endAdornment: Kg, }} /> + { + inputRef(ref ? ref.inputElement : null); + }} mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]} placeholderChar={'\u2000'} showMask diff --git a/packages/material-ui/src/InputAdornment/InputAdornment.test.js b/packages/material-ui/src/InputAdornment/InputAdornment.test.js index 1d0e7d98c0c0c3..a5c3e6973742ec 100644 --- a/packages/material-ui/src/InputAdornment/InputAdornment.test.js +++ b/packages/material-ui/src/InputAdornment/InputAdornment.test.js @@ -152,12 +152,13 @@ describe('', () => { }); it('should have the disabled pointer events class when disabledPointerEvents true', () => { - const wrapper = shallow( + const wrapper = mount( foo , ); - assert.strictEqual(wrapper.hasClass(classes.disablePointerEvents), true); + const adornment = findOutermostIntrinsic(wrapper); + assert.strictEqual(adornment.hasClass(classes.disablePointerEvents), true); }); it('should not wrap text children in a Typography when disableTypography true', () => { diff --git a/packages/material-ui/src/InputBase/InputBase.js b/packages/material-ui/src/InputBase/InputBase.js index 6aa3173c86dde3..d3c018bd68abe0 100644 --- a/packages/material-ui/src/InputBase/InputBase.js +++ b/packages/material-ui/src/InputBase/InputBase.js @@ -326,7 +326,6 @@ class InputBase extends React.Component { }); const focused = muiFormControl ? muiFormControl.focused : this.state.focused; - const variantContext = muiFormControl ? muiFormControl.variant : null; const className = classNames( classes.root, @@ -393,16 +392,16 @@ class InputBase extends React.Component { } return ( - -
- {renderPrefix - ? renderPrefix({ - ...fcs, - startAdornment, - focused, - }) - : null} - {startAdornment} +
+ {renderPrefix + ? renderPrefix({ + ...fcs, + startAdornment, + focused, + }) + : null} + {startAdornment} + - {endAdornment} -
- + + {endAdornment} +
); } }