From 0f3b0b38bc177850320aaf0226ce809d1e3b2052 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 18 Mar 2016 08:52:29 +0000 Subject: [PATCH] Make textboxes expand to fit contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This applies to any textbox which has placeholders. There are two reasons to do this: 1. Scrolling in textboxes is fiddly, especially on touch devices 2. Keeping the placeholders aligned with the textbox is fiddly too These can both be avoided by always having the textbox be larger than its contents so it never needs to scroll. By default—and unlike other block-level elements—textboxes dont expand to fit their contents. The layer with the placeholders in _does_ however, because it’s a normal block-level element. Since the layer with the placeholders always has an exact copy of what in the textbox, we can set the textbox’s height to match the height of the layer with the placeholders, and do this every time the content changes. --- app/assets/javascripts/highlightTags.js | 17 +++++++++++++++-- app/assets/stylesheets/components/textbox.scss | 3 ++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/highlightTags.js b/app/assets/javascripts/highlightTags.js index a1ecf2f37..033e6a003 100644 --- a/app/assets/javascripts/highlightTags.js +++ b/app/assets/javascripts/highlightTags.js @@ -23,6 +23,8 @@ .on("input", this.update) .on("scroll", this.maintainScrollParity); + this.initialHeight = this.$textbox.height(); + this.$backgroundMaskForeground.width( this.$textbox.width() ); @@ -32,11 +34,22 @@ }; - this.update = () => this.$backgroundMaskForeground.html( + this.resize = () => this.$textbox.height( + Math.max( + this.initialHeight, + this.$backgroundMaskForeground.outerHeight() + ) + ); + + this.replacePlaceholders = () => this.$backgroundMaskForeground.html( $('
').text(this.$textbox.val()).html().replace( tagPattern, match => `${match}` ) - ); + ) + + this.update = () => ( + this.replacePlaceholders() && this.resize() + ) this.maintainScrollParity = () => this.$backgroundMaskForeground.scrollTop( this.$textbox.scrollTop() diff --git a/app/assets/stylesheets/components/textbox.scss b/app/assets/stylesheets/components/textbox.scss index efb692c27..703b3b8cf 100644 --- a/app/assets/stylesheets/components/textbox.scss +++ b/app/assets/stylesheets/components/textbox.scss @@ -10,6 +10,7 @@ resize: none; z-index: 20; background: none; + height: 200px; } &-textbox, @@ -23,7 +24,6 @@ margin: 0; padding: 4px; overflow: hidden; - height: 200px; } &-background, @@ -36,6 +36,7 @@ color: transparent; white-space: pre-wrap; border: 2px solid transparent; + padding-bottom: $gutter; } &-background {