wot-design
Version:
Mobile UI components built on vue.js
87 lines (72 loc) • 2.43 kB
JavaScript
let hiddenTextarea
const HIDDEN_STYLE = `
height: 0 !important;
visibility: hidden !important;
overflow: hidden !important;
position: absolute !important;
z-index: -1000 !important;
top: 0 !important;
right: 0 !important;
`
const CONTEXT_STYLE = [
'letter-spacing',
'line-height',
'padding-top',
'padding-bottom',
'font-family',
'font-size',
'text-rendering',
'text-transform',
'width',
'text-indent',
'padding-left',
'padding-right',
'border-width',
'box-sizing'
]
const calculateNodeStyling = element => {
const style = window.getComputedStyle(element)
const boxSizing = style.getPropertyValue('box-sizing')
const paddingSize = parseFloat(style.getPropertyValue('padding-bottom')) + parseFloat(style.getPropertyValue('padding-top'))
const borderSize = parseFloat(style.getPropertyValue('border-bottom-width')) + parseFloat(style.getPropertyValue('border-top-width'))
const contextStyle = CONTEXT_STYLE.map(name => `${name}: ${style.getPropertyValue(name)}`).join(';')
return { contextStyle, paddingSize, borderSize, boxSizing }
}
export default function calcTextareaHeight (element, minRows = 1, maxRows = null) {
hiddenTextarea = document.createElement('textarea')
document.body.appendChild(hiddenTextarea)
let {
paddingSize,
borderSize,
boxSizing,
contextStyle
} = calculateNodeStyling(element)
hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}}`)
hiddenTextarea.value = element.value || element.placeholder || ''
let height = hiddenTextarea.scrollHeight
const result = {}
if (boxSizing === 'border-box') {
height = height + borderSize
} else if (boxSizing === 'content-box') {
height = height - paddingSize
}
hiddenTextarea.value = ''
let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize
let minHeight = singleRowHeight * minRows
if (boxSizing === 'border-box') {
minHeight = minHeight + paddingSize + borderSize
}
height = Math.max(minHeight, height)
result.minHeight = `${minHeight}px`
if (maxRows !== null) {
let maxHeight = singleRowHeight * maxRows
if (boxSizing === 'border-box') {
maxHeight = maxHeight + paddingSize + borderSize
}
height = Math.min(maxHeight, height)
}
result.height = `${height}px`
hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea)
hiddenTextarea = null
return result
}