Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use {{auto-height-textarea}} modifier on sidebar #70

Merged
merged 11 commits into from
Mar 20, 2023
1 change: 1 addition & 0 deletions web/app/components/custom-editable-field.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<Hds::Form::Textarea::Field
@value={{F.value}}
name={{field}}
{{auto-height-textarea}}
{{on "blur" F.update}}
data-test-custom-string-field-input
/>
Expand Down
4 changes: 4 additions & 0 deletions web/app/components/document/sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@
</:default>
<:editing as |F|>
<Hds::Form::Textarea::Field
{{auto-height-textarea}}
@value={{F.value}}
class="primary-textarea"
name="title"
{{on "blur" F.update}}
as |F|
Expand Down Expand Up @@ -143,7 +145,9 @@
</:default>
<:editing as |F|>
<Hds::Form::Textarea::Field
{{auto-height-textarea}}
@value={{F.value}}
class="primary-textarea"
name="summary"
{{on "blur" F.update}}
as |F|
Expand Down
57 changes: 57 additions & 0 deletions web/app/modifiers/auto-height-textarea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { assert } from "@ember/debug";
import { registerDestructor } from "@ember/destroyable";
import Modifier from "ember-modifier";

interface AutoHeightTextareaModifierSignature {
Args: {
Positional: [];
Named: {};
};
}

function cleanup(instance: AutoHeightTextareaModifier) {
let { element } = instance;

if (element) {
element.removeEventListener("input", () => {
instance.updateHeight();
});

instance.element = null;
}
}

export default class AutoHeightTextareaModifier extends Modifier<AutoHeightTextareaModifierSignature> {
element: HTMLTextAreaElement | null = null;

modify(element: HTMLTextAreaElement) {
this.element = element;

this.element.setAttribute("rows", "1");
this.element.style.resize = "none";
this.element.style.overflow = "hidden";

// set initial height
this.updateHeight();

this.element.addEventListener("input", () => {
this.updateHeight();
});

registerDestructor(this, cleanup);
}

updateHeight() {
const { element } = this;
assert("element must exist", element);

// measure any strokes
const offset = element.offsetHeight - element.clientHeight;

// temporarily set the textarea's height to 0 to force a scrollHeight
element.style.height = "0";

// set the height to the scrollHeight + offset
element.style.height = element.scrollHeight + offset + "px";
}
}
7 changes: 6 additions & 1 deletion web/app/styles/components/sidebar.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.sidebar {
@apply flex flex-col max-h-full relative z-10;

header, nav {
header,
nav {
@apply sticky top-0 mb-4;
}

Expand All @@ -11,6 +12,10 @@
height: 100%;
}

.primary-textarea {
@apply min-h-[76px];
}

.person-list {
@apply w-full list-none space-y-2;
}
Expand Down
1 change: 0 additions & 1 deletion web/app/templates/authenticated/dashboard.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<div class="hds-border-primary border-0 border-b pb-9">
<h1>Welcome back, {{this.authenticatedUser.info.given_name}}</h1>
<p>Here’s all the latest updates across the organization.</p>

</div>

{{#if this.docsWaitingForReview}}
Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"ember-focus-trap": "^1.0.1",
"ember-load-initializers": "^2.1.2",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-modifier": "^4.0.0",
"ember-modifier": "^4.1.0",
"ember-on-helper": "^0.1.0",
"ember-page-title": "^6.2.2",
"ember-qunit": "^5.1.5",
Expand Down
59 changes: 59 additions & 0 deletions web/tests/integration/modifiers/auto-height-textarea-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { fillIn, find, render } from "@ember/test-helpers";
import { module, test } from "qunit";
import { hbs } from "ember-cli-htmlbars";
import { setupRenderingTest } from "ember-qunit";
import { assert as emberAssert } from "@ember/debug";

module("Integration | Modifier | auto-height-textarea", function (hooks) {
setupRenderingTest(hooks);

test("it updates the height of the textarea", async function (assert) {
await render(hbs`
<textarea {{auto-height-textarea}} rows="5" style="line-height: 16px" />
`);

const textarea = find("textarea");
emberAssert("textarea must exist", textarea);

assert.equal(textarea.getAttribute("rows"), "1");
assert.true(textarea.style.resize === "none");

let textareaHeight = textarea.clientHeight;

await fillIn("textarea", "foo");

assert.equal(textarea.clientHeight, textareaHeight);

await fillIn("textarea", "foo\nbar");

assert.equal(textarea.clientHeight, textareaHeight * 2);

await fillIn("textarea", "foo\nbar\nbaz");

assert.equal(textarea.clientHeight, textareaHeight * 3);

await fillIn("textarea", "foo");

assert.equal(textarea.clientHeight, textareaHeight);
});

test("it shows the correct height on load", async function (assert) {
this.set("value", "foo\nbar\nbaz");

await render(hbs`
<textarea
{{auto-height-textarea}}
value={{this.value}}
style="line-height: 16px" />
`);

const textarea = find("textarea");
emberAssert("textarea must exist", textarea);

assert.equal(
textarea.clientHeight,
16 * 3,
"textarea is 3 times the line height"
);
});
});
39 changes: 24 additions & 15 deletions web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2284,7 +2284,16 @@ __metadata:
languageName: node
linkType: hard

"@sinonjs/fake-timers@npm:10.0.2, @sinonjs/fake-timers@npm:^10.0.2":
"@sinonjs/commons@npm:^3.0.0":
version: 3.0.0
resolution: "@sinonjs/commons@npm:3.0.0"
dependencies:
type-detect: 4.0.8
checksum: b4b5b73d4df4560fb8c0c7b38c7ad4aeabedd362f3373859d804c988c725889cde33550e4bcc7cd316a30f5152a2d1d43db71b6d0c38f5feef71fd8d016763f8
languageName: node
linkType: hard

"@sinonjs/fake-timers@npm:^10.0.2":
version: 10.0.2
resolution: "@sinonjs/fake-timers@npm:10.0.2"
dependencies:
Expand Down Expand Up @@ -7249,7 +7258,7 @@ __metadata:
languageName: node
linkType: hard

"diff@npm:^5.0.0":
"diff@npm:^5.0.0, diff@npm:^5.1.0":
version: 5.1.0
resolution: "diff@npm:5.1.0"
checksum: c7bf0df7c9bfbe1cf8a678fd1b2137c4fb11be117a67bc18a0e03ae75105e8533dbfb1cda6b46beb3586ef5aed22143ef9d70713977d5fb1f9114e21455fba90
Expand Down Expand Up @@ -8453,9 +8462,9 @@ __metadata:
languageName: node
linkType: hard

"ember-modifier@npm:^4.0.0":
version: 4.0.0
resolution: "ember-modifier@npm:4.0.0"
"ember-modifier@npm:^4.1.0":
version: 4.1.0
resolution: "ember-modifier@npm:4.1.0"
dependencies:
"@embroider/addon-shim": ^1.8.4
ember-cli-normalize-entity-name: ^1.0.0
Expand All @@ -8465,7 +8474,7 @@ __metadata:
peerDependenciesMeta:
ember-source:
optional: true
checksum: 8970eee22666426abed22414fc12f1547b4c02618297648ace0c22ec3db5299afe522ac2130148e6daeded0c70ad7005418c21888b8e4198e0c6b04c5f751312
checksum: 5e14a864de2184c07e59fb9bc76a09ae25d1bd37722a94751a3cef6165df22027007696c4dda03e1862cb3bbeefb046772810dda3104d05c7fe8476389c34a77
languageName: node
linkType: hard

Expand Down Expand Up @@ -10878,7 +10887,7 @@ __metadata:
ember-focus-trap: ^1.0.1
ember-load-initializers: ^2.1.2
ember-maybe-import-regenerator: ^0.1.6
ember-modifier: ^4.0.0
ember-modifier: ^4.1.0
ember-on-helper: ^0.1.0
ember-page-title: ^6.2.2
ember-power-select-with-create: ^1.0.0
Expand Down Expand Up @@ -13444,7 +13453,7 @@ __metadata:
languageName: node
linkType: hard

"nise@npm:^5.1.2":
"nise@npm:^5.1.4":
version: 5.1.4
resolution: "nise@npm:5.1.4"
dependencies:
Expand Down Expand Up @@ -15813,16 +15822,16 @@ __metadata:
linkType: hard

"sinon@npm:^15.0.1":
version: 15.0.1
resolution: "sinon@npm:15.0.1"
version: 15.0.2
resolution: "sinon@npm:15.0.2"
dependencies:
"@sinonjs/commons": ^2.0.0
"@sinonjs/fake-timers": 10.0.2
"@sinonjs/commons": ^3.0.0
"@sinonjs/fake-timers": ^10.0.2
"@sinonjs/samsam": ^7.0.1
diff: ^5.0.0
nise: ^5.1.2
diff: ^5.1.0
nise: ^5.1.4
supports-color: ^7.2.0
checksum: 4b5acff291b4650cf736bf45fc9eceed44dceca63b663cbd55926dd688fe8e9baa4b4629e296ee5d5b64245aedec5c540fea0416b8bb35bccfb98ca9e9ed87f3
checksum: 98eb555442db3985d7fe0d90e23f081f3df71adffa0a50b049bcd2abbf5c2d71a43aeaa1e3c02500164cff5233d2f102f777356ebe8bfc257cb7059c1b2778b0
languageName: node
linkType: hard

Expand Down