Initial commit
This commit is contained in:
Коммит
93fedfbbf6
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": ["plugin:github/es6", "plugin:github/browser"],
|
||||
"parser": "babel-eslint"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
dist/
|
||||
node_modules/
|
||||
package-lock.json
|
||||
yarn.lock
|
|
@ -0,0 +1,9 @@
|
|||
language: node_js
|
||||
sudo: required
|
||||
node_js:
|
||||
- "node"
|
||||
addons:
|
||||
chrome: stable
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2018 GitHub, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,27 @@
|
|||
# Textarea Autosize
|
||||
|
||||
Autosizes textarea to size of it's contents.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install @github/textarea-autosize
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import autosize from '@github/textarea-autosize'
|
||||
autosize(document.querySelector('textarea.foo'))
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the MIT license. See LICENSE for details.
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body {
|
||||
font: 20px Helvetica;
|
||||
padding: 20px;
|
||||
}
|
||||
textarea {
|
||||
width: 500px;
|
||||
min-height: 100px;
|
||||
display: block;
|
||||
}
|
||||
.styled {
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
font-family: Helvetica, sans-serif;
|
||||
font-size: 23px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<textarea autofocus></textarea>
|
||||
<textarea class="styled"></textarea>
|
||||
<p>
|
||||
<button>Load long text</button>
|
||||
<input type=reset>
|
||||
</p>
|
||||
<div id="long-text" hidden>Long and well reasoned argument
|
||||
about talking about long and well reasoned arguments
|
||||
and how they long
|
||||
and well reasoned
|
||||
and argue things of value.
|
||||
|
||||
Maybe.
|
||||
|
||||
Honestly, though, this is just long.
|
||||
|
||||
Long enough, in any case.
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script type="module">
|
||||
import autosize from '../dist/textarea-autosize.esm.js'
|
||||
|
||||
for (const textarea of document.getElementsByTagName('textarea')) {
|
||||
autosize(textarea)
|
||||
}
|
||||
|
||||
document.querySelector('button').addEventListener('click', event => {
|
||||
event.preventDefault()
|
||||
for (const textarea of document.getElementsByTagName('textarea')) {
|
||||
textarea.value = document.getElementById('long-text').textContent
|
||||
textarea.dispatchEvent(new Event('change'))
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "@github/textarea-autosize",
|
||||
"description": "Autosizes textarea to size of it's contents.",
|
||||
"version": "0.0.0",
|
||||
"main": "dist/textarea-autosize.umd.js",
|
||||
"module": "dist/textarea-autosize.esm.js",
|
||||
"license": "MIT",
|
||||
"repository": "github/textarea-autosize",
|
||||
"files": ["dist"],
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint textarea-autosize.js",
|
||||
"prebuild": "npm run clean && npm run lint && mkdir dist",
|
||||
"build": "rollup -c && npm run build-flow",
|
||||
"build-flow":
|
||||
"cp textarea-autosize.js.flow dist/textarea-autosize.esm.js.flow && cp textarea-autosize.js.flow dist/textarea-autosize.umd.js.flow",
|
||||
"test": "echo",
|
||||
"pretest": "npm run build",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-preset-es2015-rollup": "^3.0.0",
|
||||
"eslint": "^5.1.0",
|
||||
"eslint-plugin-github": "^1.1.3",
|
||||
"rollup": "^0.64.0",
|
||||
"rollup-plugin-babel": "^3.0.7"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
module.exports = require('eslint-plugin-github/prettier.config')
|
|
@ -0,0 +1,23 @@
|
|||
import babel from 'rollup-plugin-babel'
|
||||
|
||||
const pkg = require('./package.json')
|
||||
|
||||
export default {
|
||||
input: 'textarea-autosize.js',
|
||||
output: [
|
||||
{
|
||||
file: pkg['module'],
|
||||
format: 'es'
|
||||
},
|
||||
{
|
||||
file: pkg['main'],
|
||||
format: 'umd',
|
||||
name: 'textareaAutosize'
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
babel({
|
||||
presets: ['es2015-rollup']
|
||||
})
|
||||
]
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
export default function autosize(textarea) {
|
||||
let previousValue = null
|
||||
let isUserResized = false
|
||||
|
||||
let x
|
||||
let y
|
||||
let height
|
||||
|
||||
function onUserResize(event) {
|
||||
if (x !== event.clientX || y !== event.clientY) {
|
||||
const newHeight = textarea.style.height
|
||||
if (height && height !== newHeight) {
|
||||
isUserResized = true
|
||||
textarea.style.maxHeight = ''
|
||||
textarea.removeEventListener('mousemove', onUserResize)
|
||||
}
|
||||
height = newHeight
|
||||
}
|
||||
|
||||
x = event.clientX
|
||||
y = event.clientY
|
||||
}
|
||||
|
||||
const document = textarea.ownerDocument
|
||||
const documentElement = document.documentElement
|
||||
|
||||
function overflowOffset() {
|
||||
let offsetTop = 0
|
||||
let el = textarea
|
||||
|
||||
while (el !== document.body && el !== null) {
|
||||
offsetTop += el.offsetTop || 0
|
||||
el = el.offsetParent
|
||||
}
|
||||
|
||||
const top = offsetTop - document.defaultView.pageYOffset
|
||||
const bottom = documentElement.clientHeight - (top + textarea.offsetHeight)
|
||||
return {top, bottom}
|
||||
}
|
||||
|
||||
function sizeToFit() {
|
||||
if (isUserResized) return
|
||||
if (textarea.value === previousValue) return
|
||||
if (textarea.offsetWidth <= 0 && textarea.offsetHeight <= 0) return
|
||||
|
||||
const {top, bottom} = overflowOffset()
|
||||
if (top < 0 || bottom < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const maxHeight = Number(getComputedStyle(textarea).height.replace(/px/, '')) + bottom
|
||||
textarea.style.maxHeight = `${maxHeight - 100}px`
|
||||
|
||||
const container = textarea.parentElement
|
||||
if (container instanceof HTMLElement) {
|
||||
const containerHeight = container.style.height
|
||||
container.style.height = getComputedStyle(container).height
|
||||
textarea.style.height = 'auto'
|
||||
textarea.style.height = `${textarea.scrollHeight}px`
|
||||
container.style.height = containerHeight
|
||||
height = textarea.style.height
|
||||
}
|
||||
|
||||
previousValue = textarea.value
|
||||
}
|
||||
|
||||
function onFormReset() {
|
||||
isUserResized = false
|
||||
textarea.style.height = ''
|
||||
textarea.style.maxHeight = ''
|
||||
}
|
||||
|
||||
textarea.addEventListener('mousemove', onUserResize)
|
||||
textarea.addEventListener('input', sizeToFit)
|
||||
textarea.addEventListener('change', sizeToFit)
|
||||
const form = textarea.form
|
||||
if (form) form.addEventListener('reset', onFormReset)
|
||||
if (textarea.value) sizeToFit()
|
||||
|
||||
return {
|
||||
unsubscribe() {
|
||||
textarea.removeEventListener('mousemove', onUserResize)
|
||||
textarea.removeEventListener('input', sizeToFit)
|
||||
textarea.removeEventListener('change', sizeToFit)
|
||||
if (form) form.removeEventListener('reset', onFormReset)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/* @flow strict */
|
||||
|
||||
declare export default function autosize(textarea: HTMLTextAreaElement): Subscription;
|
||||
|
||||
interface Subscription {
|
||||
unsubscribe(): void;
|
||||
}
|
Загрузка…
Ссылка в новой задаче