Skip to content

Commit

Permalink
fix(TextArea): compute height when hidden (#1793)
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason committed Jun 23, 2017
1 parent 1b6589e commit a6b979d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Form, TextArea } from 'semantic-ui-react'

const TextAreaExampleAutoHeightRows = () => (
<Form>
<TextArea autoHeight placeholder='Try adding multiple lines' rows={1} />
<TextArea autoHeight placeholder='Try adding multiple lines' rows={2} />
</Form>
)

Expand Down
39 changes: 29 additions & 10 deletions src/addons/TextArea/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
* @see Form
*/
class TextArea extends Component {
state = {}

static _meta = {
name: 'TextArea',
type: META.TYPES.ADDON,
Expand Down Expand Up @@ -83,29 +85,46 @@ class TextArea extends Component {
const { autoHeight } = this.props
if (!this.ref || !autoHeight) return

let { borderTopWidth, borderBottomWidth } = window.getComputedStyle(this.ref)
borderTopWidth = parseInt(borderTopWidth, 10)
borderBottomWidth = parseInt(borderBottomWidth, 10)

this.ref.style.resize = 'none'
this.ref.style.height = 'auto'
this.ref.style.height = (this.ref.scrollHeight + borderTopWidth + borderBottomWidth) + 'px'
const {
borderBottomWidth,
borderTopWidth,
lineHeight,
minHeight,
paddingBottom,
paddingTop,
} = window.getComputedStyle(this.ref)

const boxModelHeight = _.sum([
borderBottomWidth,
borderTopWidth,
paddingBottom,
paddingTop,
].map(x => parseFloat(x)))
const textRows = Math.max(this.ref.rows, this.ref.value.split('\n').length)
const textHeight = parseFloat(lineHeight) * textRows

// respect style.minHeight
this.setState((prevState, props) => ({
height: Math.max(parseFloat(minHeight), Math.ceil(boxModelHeight + textHeight)) + 'px',
}))
}

render() {
const { rows, style, value } = this.props
const minHeight = _.get(style, 'minHeight', 0)
const { autoHeight, rows, style, value } = this.props
const { height } = this.state

const rest = getUnhandledProps(TextArea, this.props)
const ElementType = getElementType(TextArea, this.props)

const resize = autoHeight ? 'none' : ''

return (
<ElementType
{...rest}
onChange={this.handleChange}
ref={this.handleRef}
rows={rows}
style={{ ...style, minHeight }}
style={{ height, resize, ...style }}
value={value}
/>
)
Expand Down
23 changes: 3 additions & 20 deletions test/specs/addons/TextArea/TextArea-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,15 @@ describe('TextArea', () => {
// simplify styles to make height assertions easier
const style = { padding: 0, fontSize: '10px', lineHeight: 1, border: 'none' }

const assertHeight = (height, minHeight = '0px') => {
const assertHeight = (height) => {
const element = document.querySelector('textarea')

if (!height) {
element.style.should.have.property('minHeight', minHeight)
element.style.should.have.property('resize', '')
element.style.should.have.property('height', '')
return
}

element.style.should.have.property('minHeight', minHeight)
element.style.should.have.property('resize', 'none')

// CI renders textareas with an extra pixel
Expand All @@ -74,8 +72,8 @@ describe('TextArea', () => {
})

it('depends on minHeight value of style', () => {
wrapperMount(<TextArea autoHeight style={{ ...style, minHeight: 50 }} />)
assertHeight('50px', '50px')
wrapperMount(<TextArea autoHeight style={{ ...style, minHeight: '50px' }} />)
assertHeight('50px')
})

it('depends on rows value', () => {
Expand Down Expand Up @@ -164,20 +162,5 @@ describe('TextArea', () => {
wrapper.should.have.style('margin-top', '1em')
wrapper.should.have.style('top', '0')
})

it('has default value of minHeight', () => {
shallow(<TextArea />)
.should.have.style('min-height', '0')
})

it('sets number value of minHeight', () => {
shallow(<TextArea style={{ minHeight: 10 }} />)
.should.have.style('min-height', '10px')
})

it('sets string value of minHeight', () => {
shallow(<TextArea style={{ minHeight: '10em' }} />)
.should.have.style('min-height', '10em')
})
})
})

0 comments on commit a6b979d

Please sign in to comment.