[#160] Add auto-resizing textareas
in order to prevent users from having to scroll in secrets Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
f2a7af30b2
commit
98268f1457
3 changed files with 80 additions and 5 deletions
|
@ -31,11 +31,11 @@
|
||||||
>
|
>
|
||||||
<div class="col-12 mb-3">
|
<div class="col-12 mb-3">
|
||||||
<label for="createSecretData">{{ $t('label-secret-data') }}</label>
|
<label for="createSecretData">{{ $t('label-secret-data') }}</label>
|
||||||
<textarea
|
<grow-area
|
||||||
id="createSecretData"
|
id="createSecretData"
|
||||||
v-model="secret"
|
v-model="secret"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
rows="5"
|
:rows="2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -117,6 +117,7 @@
|
||||||
|
|
||||||
import appCrypto from '../crypto.js'
|
import appCrypto from '../crypto.js'
|
||||||
import { bytesToHuman } from '../helpers'
|
import { bytesToHuman } from '../helpers'
|
||||||
|
import GrowArea from './growarea.vue'
|
||||||
import OTSMeta from '../ots-meta'
|
import OTSMeta from '../ots-meta'
|
||||||
|
|
||||||
const defaultExpiryChoices = [
|
const defaultExpiryChoices = [
|
||||||
|
@ -147,6 +148,8 @@ const passwordCharset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS
|
||||||
const passwordLength = 20
|
const passwordLength = 20
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: { GrowArea },
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
canCreate() {
|
canCreate() {
|
||||||
return (this.secret.trim().length > 0 || this.selectedFileMeta.length > 0) && !this.maxFileSizeExceeded && !this.invalidFilesSelected
|
return (this.secret.trim().length > 0 || this.selectedFileMeta.length > 0) && !this.maxFileSizeExceeded && !this.invalidFilesSelected
|
||||||
|
|
71
src/components/growarea.vue
Normal file
71
src/components/growarea.vue
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<textarea
|
||||||
|
ref="area"
|
||||||
|
v-model="data"
|
||||||
|
style="resize: none;"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.data = this.value
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
changeSize() {
|
||||||
|
const verticalBorderSize = this.getStyle('borderTopWidth') + this.getStyle('borderBottomWidth') || 0
|
||||||
|
const verticalPaddingSize = this.getStyle('paddingTop') + this.getStyle('paddingBottom') || 0
|
||||||
|
|
||||||
|
const smallestHeight = this.getStyle('lineHeight') * this.rows + verticalBorderSize + verticalPaddingSize
|
||||||
|
this.$refs.area.style.height = `${smallestHeight}px`
|
||||||
|
|
||||||
|
const newHeight = this.$refs.area.scrollHeight + verticalBorderSize
|
||||||
|
this.$refs.area.style.height = `${newHeight}px`
|
||||||
|
},
|
||||||
|
|
||||||
|
getStyle(name) {
|
||||||
|
return parseInt(getComputedStyle(this.$refs.area, null)[name])
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.changeSize()
|
||||||
|
},
|
||||||
|
|
||||||
|
name: 'GrowArea',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
rows: {
|
||||||
|
default: 4,
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
value: {
|
||||||
|
default: '',
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
data(to, from) {
|
||||||
|
this.changeSize()
|
||||||
|
if (to !== from) {
|
||||||
|
this.$emit('input', to)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
value(to) {
|
||||||
|
if (to !== this.data) {
|
||||||
|
this.data = to
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -27,11 +27,11 @@
|
||||||
v-if="secret"
|
v-if="secret"
|
||||||
class="input-group mb-3"
|
class="input-group mb-3"
|
||||||
>
|
>
|
||||||
<textarea
|
<grow-area
|
||||||
class="form-control"
|
class="form-control"
|
||||||
readonly
|
readonly
|
||||||
:value="secret"
|
:value="secret"
|
||||||
rows="4"
|
:rows="4"
|
||||||
/>
|
/>
|
||||||
<div class="d-flex align-items-start p-0">
|
<div class="d-flex align-items-start p-0">
|
||||||
<div
|
<div
|
||||||
|
@ -85,10 +85,11 @@ import appClipboardButton from './clipboard-button.vue'
|
||||||
import appCrypto from '../crypto.js'
|
import appCrypto from '../crypto.js'
|
||||||
import appQrButton from './qr-button.vue'
|
import appQrButton from './qr-button.vue'
|
||||||
import { bytesToHuman } from '../helpers'
|
import { bytesToHuman } from '../helpers'
|
||||||
|
import GrowArea from './growarea.vue'
|
||||||
import OTSMeta from '../ots-meta'
|
import OTSMeta from '../ots-meta'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { appClipboardButton, appQrButton },
|
components: { GrowArea, appClipboardButton, appQrButton },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in a new issue