diff --git a/src/components/Input/README.md b/src/components/Input/README.md index 6edd604..6707f7a 100644 --- a/src/components/Input/README.md +++ b/src/components/Input/README.md @@ -43,3 +43,8 @@ An autoresizeable textarea: ```js ``` + +An autoresizeable textarea with custom initial number of rows: +```js + +``` diff --git a/src/components/Input/__snapshots__/input.spec.js.snap b/src/components/Input/__snapshots__/input.spec.js.snap index a78a678..adc8fdc 100644 --- a/src/components/Input/__snapshots__/input.spec.js.snap +++ b/src/components/Input/__snapshots__/input.spec.js.snap @@ -41,6 +41,7 @@ exports[`Input autoresizing works correctly 1`] = ` onKeyPress={[Function]} onKeyUp={[Function]} readOnly={false} + rows={2} tabIndex={0} value="This is some value" > @@ -97,9 +98,10 @@ exports[`Input autoresizing works correctly 2`] = ` onKeyPress={[Function]} onKeyUp={[Function]} readOnly={false} + rows={2} style={ Object { - "height": "0px", + "height": "98px", } } tabIndex={0} diff --git a/src/components/Input/index.js b/src/components/Input/index.js index 519b9cb..2936f86 100644 --- a/src/components/Input/index.js +++ b/src/components/Input/index.js @@ -169,8 +169,12 @@ class Input extends React.Component { handleAutoResize() { // height has to be reset first because if not it keeps increasing every time user will type a character // setting actual height must be done in setState callback, because React might optimize this into one setState call + // scrollHeight includes padding, we need to compensate this + // keep value in sync with padding-bottom in .wds-input__field styles + const BOTTOM_PADDING = 2; + this.setState({dynamicTextareaHeight: 'auto'}, () => { - this.setState({dynamicTextareaHeight: `${this.input.scrollHeight}px`}); + this.setState({dynamicTextareaHeight: `${this.input.scrollHeight - BOTTOM_PADDING}px`}); }); // to prevent scroll jumping @@ -180,12 +184,11 @@ class Input extends React.Component { renderMultiline() { const props = { ...this.getSharedInputProps(), + rows: this.props.rows, }; if (this.isAutoResize()) { props.onInput = this.handleAutoResize; - } else { - props.rows = this.props.rows; } if (this.state.dynamicTextareaHeight) { @@ -291,7 +294,7 @@ Input.propTypes = { /** * Initial number of rows * - * **Note**: This prop only makes sense for multiline inputs. Does not work when `resize="auto"` is set + * **Note**: This prop only makes sense for multiline inputs. */ rows: PropTypes.number, /** diff --git a/src/components/Input/input.spec.js b/src/components/Input/input.spec.js index 895de94..cf807bd 100644 --- a/src/components/Input/input.spec.js +++ b/src/components/Input/input.spec.js @@ -140,9 +140,14 @@ test('Input autoresizing works correctly', () => { expect(component).toMatchSnapshot(); - const textrea = component.find('textarea'); + const textarea = component.find('textarea'); - textrea.simulate('input', {target: {value: 'This is value to test \n if autoresizing works'}}); + // because scrollHeight is a getter + Object.defineProperty(textarea.getDOMNode(), 'scrollHeight', { + value: 100, + }); + + textarea.simulate('input', {target: {value: 'This is value to test \n if autoresizing works'}}); expect(component).toMatchSnapshot(); }); diff --git a/src/components/Input/styles.scss b/src/components/Input/styles.scss index 90430b8..139ca39 100644 --- a/src/components/Input/styles.scss +++ b/src/components/Input/styles.scss @@ -15,6 +15,7 @@ font-size: $wds-typescale-size-base; line-height: 1em; padding: 0; + // keep value in sync with `BOTTOM_PADDING` from Input component padding-bottom: 2px; resize: none; width: 100%;