Auto-expand text input height?

In the Drag & Drop interface, is there a way to make an auto-expanding text input? I want the text input to appear as a single line height but if I type or paste text in that is longer than a single line, I want the text input to visibly grow to a height that can display the full text. Is this possible? The bottom image is what I’m wanting:

Hello @tatiang
I think you can try something like this

Here is the project I built: Thunkable

2 Likes

That’s an interesting approach. Thank you for posting it! Not perfect but maybe I can work with that…

1 Like

If you have any issues during the implementation, please let me know. Happy to see this functionality completed.

1 Like

I modified it so that it checks if the length of text input mod 18 equals 0 (Len%18=0). And if so, I multiply the height by a constant (e.g. the original height of the component) using the multiple of 18 as a multiplier (that is, if the length is 54, then I multiply by 3 since 54 ÷ 18 = 3). That works pretty well too.

The issues I’m having are that I’m not using a mono spaced font so “a” is narrower than “W”, etc. So 18 won’t always work. Also, it looks fine for 1 line or more than 2 lines but when there are exactly 2 lines of text, the component is too short (not enough padding).

I’m not sure what happened to the modified project. I worked on it and it’s not in my list of projects. I’d share it here but I may have to re-create it first.

Thanks for the offer! I was thinking I might come up with a font map list that has pairings for each letter/symbol and its pixel width. It’s kind of a pain to do all that and definitely not very dynamic but it might work and look really good in a pinch.

Edit: found it! Thunkable

Bing/ChatGPT provided this code (after a few iterations of prompts) to determine the width of a text string (or single character depending on how it’s coded). I’m using it with Arial 18 pt.

<!DOCTYPE html>
<html>
<head>
	<title>Canvas Example</title>
</head>
<body>
	<canvas id="myCanvas" width="200" height="200"></canvas>
	<p id="width"></p>
	<script>
		let font = "18px Arial";
		let text = "aaaaa";
		let canvas = document.getElementById("myCanvas");
		let context = canvas.getContext("2d");
		context.font = font;
		let size = context.measureText(text);
		context.fillText(text, 0, 20);
		document.getElementById("width").textContent = "Width: " + size.width;
	</script>
</body>
</html>

This code will generate a list of keyboard letters, numbers and symbols and their pixel widths. I’m still working to format it better.

Widths: a [10.0107421875], b [10.0107421875], c [9], d [10.0107421875], e [10.0107421875], f [5.0009765625], g [10.0107421875], h [10.0107421875], i [3.9990234375], j [3.9990234375], k [9], l [3.9990234375], m [14.994140625], n [10.0107421875], o [10.0107421875], p [10.0107421875], q [10.0107421875], r [5.994140625], s [9], t [5.0009765625], u [10.0107421875], v [9], w [12.9990234375], x [9], y [9], z [9], 0 [10.0107421875], 1 [10.0107421875], 2 [10.0107421875], 3 [10.0107421875], 4 [10.0107421875], 5 [10.0107421875], 6 [10.0107421875], 7 [10.0107421875], 8 [10.0107421875], 9 [10.0107421875], ! [5.0009765625], @ [18.2724609375], # [10.0107421875], $ [10.0107421875], % [16.0048828125], ^ [8.4462890625], & [12.005859375], * [7.0048828125], ( [5.994140625], ) [5.994140625], _ [10.0107421875], + [10.51171875], - [5.994140625], = [10.51171875], [ [5.0009765625], ] [5.0009765625], { [6.01171875], } [6.01171875], \ [5.0009765625], | [4.67578125], ; [5.0009765625], ' [3.4365234375], : [5.0009765625], " [6.3896484375], , [5.0009765625], . [5.0009765625], / [5.0009765625], < [10.51171875], > [10.51171875], ? [10.0107421875]
<!DOCTYPE html>
<html>
<head>
	<title>Canvas Example</title>
</head>
<body>
	<canvas id="myCanvas" width="200" height="200"></canvas>
	<p id="width"></p>
	<script>
		let font = "18px Arial";
		let text = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}\\|;':\",./<>?";
		let canvas = document.getElementById("myCanvas");
		let context = canvas.getContext("2d");
		context.font = font;
		let width = [];
		for (let i = 0; i < text.length; i++) {
			let size = context.measureText(text[i]);
			width.push(text[i] + " [" + size.width + "]");
		}
		document.getElementById("width").textContent = "Widths: " + width.join(", ");
	</script>
</body>
</html>

I then asked Bing/ChatGPT to calculate the average of the pixel widths it generated. It came up with an average character width of 9.5 pixels. So I might use that in my calculations although I’m not convinced that all of the values it provided are accurate. Or I might just use the width of “n” which is 10 pixels.

For example, in your project, I can enter “n” 17 times before the end of the line is reached so I guess the 18th character would need to be on the next line which – hey! – is exactly what you had.

And here is the list of pixel widths split into two CSV lists (thanks, ChatGPT!):

a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,!,@,#,$,%,^,&,*,(,),_,+,-,=,[,],{,},\,|,;,',:,",,,.,/,<,>,?

10.0,10.0,9.0,10.0,10.0,5.0,10.0,10.0,4.0,4.0,9.0,4.0,15.0,10.0,10.0,10.0,10.0,6.0,9.0,5.0,10.0,9.0,13.0,9.0,9.0,9.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,5.0,18.3,10.0,10.0,16.0,8.4,12.0,7.0,6.0,6.0,10.5,5.0,10.5,5.0,5.0,3.4,5.0,6.4,5.0,5.0,5.0,10.5,10.5,10.0

Edit: oops, forgot space (" ") which has a width of 5.0 pixels.

:star: This project will display the pixel width of a string entered in the text input component: Thunkable

:star: :star: And here’s a version with the start of a working dynamic text input height based on pixel width of characters: Thunkable. It allows for variable character width so that if you enter “a” 17 times, that’s not the same as entering “W” 17 times.

:star: :star: :star: Improved code, now checking based on Text Input width so you should be able to resize the Text Input component and still have it wrap text and auto-size its height. Thunkable

I had neglected to include capital letters… oops! This version has them and I’ve also modified the blocks to be a bit more efficient and dynamic and not to rely on static values as much.

Punctuation is returning a NaN value and resetting the calculated height of the text input. I know the comma (,) is a problem due to the fact that I’m using csv lists. Just not sure what to do about that. I guess I should use a different delimiter.