Skip to content

Commit 37fdd10

Browse files
committed
Create first try at CSS-driven autogrow, which works on Firefox but does not shrink again on Chromium
1 parent fea11e3 commit 37fdd10

File tree

8 files changed

+124
-2
lines changed

8 files changed

+124
-2
lines changed

code-input.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,12 @@ var codeInput = {
556556
syncSize() {
557557
// Synchronise the size of the pre/code and textarea elements
558558
const height = getComputedStyle(this.getStyledHighlightingElement()).height;
559+
this.textareaElement.style.height = 0;
559560
this.textareaElement.style.height = height;
560561
this.textareaElement.style.setProperty("--code-input_synced-height", height);
561562

562563
const width = getComputedStyle(this.getStyledHighlightingElement()).width;
564+
this.textareaElement.style.width = 0;
563565
this.textareaElement.style.width = width;
564566
this.textareaElement.style.setProperty("--code-input_synced-width", width);
565567
}

docs/plugins/_index.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,41 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
124124
</html>
125125
```
126126

127+
#### `Autogrow`: Let code-input elements resize to fit their content (optionally between limits) {#playground-preset-prism-line-numbers}
128+
129+
```
130+
<!DOCTYPE html>
131+
<html>
132+
<body>
133+
<!--For convenience, this demo uses files from JSDelivr CDN; for more privacy and security download and host them yourself.-->
134+
<!--Prism+code-input-->
135+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
136+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/plugins/autoloader/prism-autoloader.min.js"></script>
137+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/themes/prism.min.css"></link>
138+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/code-input.min.js"></script>
139+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/code-input.min.css">
140+
141+
142+
<!--Import-->
143+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/plugins/autogrow.min.css"/>
144+
145+
<script>
146+
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [
147+
// CSS only - don't pass here
148+
]));
149+
</script>
150+
<p>Enter newlines to grow vertically:</p>
151+
<code-input class="code-input_autogrow_height" language="Markdown"></code-input>
152+
<p>Type to grow horizontally:</p>
153+
<code-input class="code-input_autogrow_width" language="Markdown"></code-input>
154+
<p>Grows vertically between 100px and 200px:</p>
155+
<code-input class="code-input_autogrow_height" style="--code-input_autogrow_min-height: 100px; --code-input_autogrow_max-height: 200px;" language="Markdown"></code-input>
156+
<p>Grows horizontally between 100px and 200px:</p>
157+
<code-input class="code-input_autogrow_width" style="--code-input_autogrow_min-width: 100px; --code-input_autogrow_max-width: 200px;" language="Markdown"></code-input>
158+
</body>
159+
</html>
160+
```
161+
127162
#### `FindAndReplace`: Add an openable dialog to find and replace matches to a search term, including highlighting the matches {#playground-preset-find-and-replace}
128163

129164
```

plugins/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ Files: [autodetect.js](./autodetect.js)
2929

3030
[🚀 *Demo*](https://v2.code-input-js.org/plugins/#playground-preset-autodetect)
3131

32+
### Autogrow
33+
Make code-input elements resize automatically and fit their content live using CSS classes, optionally between a minimum and maximum size specified using CSS variables.
34+
35+
Files: [autogrow.css](./autogrow.css) (NO JS FILE)
36+
37+
[🚀 *Demo*](https://v2.code-input-js.org/plugins/#playground-preset-autogrow)
38+
3239
### Find and Replace
3340
Add Find-and-Replace (Ctrl+F for find, Ctrl+H for replace by default, or when JavaScript triggers it) functionality to the code editor.
3441

plugins/autogrow.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ code-input.code-input_autogrow_height {
1515
max-height: var(--code-input_autogrow_max-height);
1616
}
1717
code-input.code-input_autogrow_height textarea {
18-
height: var(--code-input_autogrow_min-height)!important; /* So minimum height possible while containing highlighted code */
18+
height: calc(var(--code-input_autogrow_min-height) - var(--padding-top, 16px) - var(--padding-bottom, 16px))!important; /* So minimum height possible while containing highlighted code */
1919
min-height: max(var(--code-input_synced-height), calc(100% - var(--padding-top, 16px) - var(--padding-bottom, 16px)));
2020
}
2121

@@ -27,6 +27,6 @@ code-input.code-input_autogrow_width {
2727
}
2828

2929
code-input.code-input_autogrow_width textarea {
30-
width: var(--code-input_autogrow_min-width)!important; /* So minimum width possible while containing highlighted code */
30+
width: calc(var(--code-input_autogrow_min-width) - var(--padding-left, 16px) - var(--padding-right, 16px))!important; /* So minimum width possible while containing highlighted code */
3131
min-width: max(var(--code-input_synced-width), calc(100% - var(--padding-left, 16px) - var(--padding-right, 16px)));
3232
}

plugins/prism-line-numbers.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,9 @@ code-input .line-numbers .line-numbers-rows {
3333
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused) .line-numbers .line-numbers-rows {
3434
top: calc(var(--padding-top) + 3em);
3535
}
36+
37+
/* Compatibility with autogrow plugin */
38+
code-input.line-numbers.code-input_autogrow_width textarea, .line-numbers code-input.code-input_autogrow_width textarea {
39+
width: calc(var(--code-input_autogrow_min-width) - max(3.8em, var(--padding-left, 16px)) - var(--padding-right, 16px))!important; /* So minimum width possible while containing highlighted code */
40+
min-width: max(var(--code-input_synced-width), calc(100% - max(3.8em, var(--padding-left, 16px)) - var(--padding-right, 16px)));
41+
}

tests/hljs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<script src="../plugins/auto-close-brackets.js"></script>
2323
<script src="../plugins/autocomplete.js"></script>
2424
<link rel="stylesheet" href="../plugins/autocomplete.css">
25+
<link rel="stylesheet" href="../plugins/autogrow.css">
2526
<script src="../plugins/autodetect.js"></script>
2627
<script src="../plugins/find-and-replace.js"></script>
2728
<link rel="stylesheet" href="../plugins/find-and-replace.css">

tests/prism.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<script src="../plugins/auto-close-brackets.js"></script>
2222
<script src="../plugins/autocomplete.js"></script>
2323
<link rel="stylesheet" href="../plugins/autocomplete.css">
24+
<link rel="stylesheet" href="../plugins/autogrow.css">
2425
<script src="../plugins/find-and-replace.js"></script>
2526
<link rel="stylesheet" href="../plugins/find-and-replace.css">
2627
<script src="../plugins/go-to-line.js"></script>

tests/tester.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,76 @@ console.log("I've got another line!", 2 &lt; 3, "should be true.");
478478
assertEqual("Autodetect", "Detects CSS", codeInputElement.getAttribute("language"), "css");
479479
}
480480

481+
// Autogrow
482+
// Replace all code
483+
textarea.selectionStart = 0;
484+
textarea.selectionEnd = textarea.value.length;
485+
backspace(textarea);
486+
textarea.parentElement.classList.add("code-input_autogrow_height");
487+
await waitAsync(100); // Wait for height to update
488+
489+
const emptyHeight = textarea.parentElement.clientHeight;
490+
addText(textarea, "// a\n// b\n// c\n// d\n// e\n// f\n// g");
491+
await waitAsync(100); // Wait for height to update
492+
493+
const fullHeight = textarea.parentElement.clientHeight;
494+
testAssertion("Autogrow", "Content Increases Height", fullHeight > emptyHeight, `${fullHeight} should be > ${emptyHeight}`);
495+
textarea.parentElement.style.setProperty("font-size", "50%");
496+
await waitAsync(200); // Wait for height to update
497+
498+
testAssertion("Autogrow", "font-size Decrease Decreases Height", textarea.parentElement.clientHeight < fullHeight, `${textarea.parentElement.clientHeight} should be < ${fullHeight}`);
499+
textarea.parentElement.style.setProperty("font-size", "100%");
500+
textarea.parentElement.style.removeProperty("font-size");
501+
textarea.parentElement.style.setProperty("--code-input_autogrow_min-height", (fullHeight + 10) + "px");
502+
textarea.blur(); // Prevent focus instruction bar from affecting height
503+
await waitAsync(200); // Wait for height to update
504+
505+
assertEqual("Autogrow", "--code-input_autogrow_min-height Sets Height", textarea.parentElement.clientHeight, fullHeight + 10);
506+
textarea.focus(); // Enable inserting text again
507+
textarea.parentElement.style.removeProperty("--code-input_autogrow_min-height");
508+
textarea.parentElement.style.setProperty("--code-input_autogrow_max-height", (fullHeight - 10) + "px");
509+
await waitAsync(100); // Wait for height to update
510+
511+
assertEqual("Autogrow", "--code-input_autogrow_max-height Sets Height", textarea.parentElement.clientHeight, fullHeight - 10);
512+
textarea.parentElement.style.removeProperty("--code-input_autogrow_max-height");
513+
textarea.parentElement.style.removeProperty("--code-input_autogrow_max-height");
514+
await waitAsync(100); // Wait for height to update
515+
516+
textarea.selectionStart = 0;
517+
textarea.selectionEnd = textarea.value.length;
518+
backspace(textarea);
519+
textarea.parentElement.classList.add("code-input_autogrow_width");
520+
await waitAsync(100); // Wait for width to update
521+
522+
const emptyWidth = textarea.parentElement.clientWidth;
523+
addText(textarea, "// A very very very very extremely vastly very very very very long line of code is written here in this very comment; yes, this very comment!");
524+
await waitAsync(100); // Wait for width to update
525+
526+
const fullWidth = textarea.parentElement.clientWidth;
527+
testAssertion("Autogrow", "Content Increases Width", fullWidth > emptyWidth, `${fullWidth} should be > ${emptyWidth}`);
528+
textarea.parentElement.style.setProperty("font-size", "50%");
529+
await waitAsync(200); // Wait for width to update
530+
531+
testAssertion("Autogrow", "font-size Decrease Decreases Width", textarea.parentElement.clientWidth < fullWidth, `${textarea.parentElement.clientWidth} should be < ${fullWidth}`);
532+
textarea.parentElement.style.setProperty("font-size", "100%");
533+
textarea.parentElement.style.removeProperty("font-size");
534+
textarea.parentElement.style.setProperty("--code-input_autogrow_min-width", (fullWidth + 10) + "px");
535+
await waitAsync(200); // Wait for width to update
536+
537+
assertEqual("Autogrow", "--code-input_autogrow_min-width Sets Width", textarea.parentElement.clientWidth, fullWidth + 10);
538+
textarea.parentElement.style.removeProperty("--code-input_autogrow_min-width");
539+
textarea.parentElement.style.setProperty("--code-input_autogrow_max-width", (fullWidth - 10) + "px");
540+
await waitAsync(100); // Wait for width to update
541+
542+
assertEqual("Autogrow", "--code-input_autogrow_max-width Sets Width", textarea.parentElement.clientWidth, fullWidth - 10);
543+
textarea.parentElement.style.removeProperty("--code-input_autogrow_max-width");
544+
textarea.parentElement.style.removeProperty("--code-input_autogrow_max-width");
545+
546+
textarea.parentElement.classList.remove("code-input_autogrow_height");
547+
textarea.parentElement.classList.remove("code-input_autogrow_width");
548+
549+
// TODO add reaons to above testAssertions; check why min-width failing; manual tests to check properly fits; prompt tests; fix no-content hljs.html autogrow-both-ways sizing; test with unregistered.
550+
481551
// FindAndReplace
482552
// Replace all code
483553
textarea.selectionStart = 0;

0 commit comments

Comments
 (0)