Skip to content

Commit

Permalink
feat: improve auto grow functionality for TextArea
Browse files Browse the repository at this point in the history
Signed-off-by: Mason Hu <[email protected]>
  • Loading branch information
mas-who authored and edlerd committed Jan 19, 2024
1 parent 9e9ffc5 commit b27d6e9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
1 change: 1 addition & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export default defineConfig({
return require("./cypress/plugins/index.js")(on, config);
},
},
experimentalStudio: true,
});
24 changes: 24 additions & 0 deletions cypress/e2e/textArea.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
context("TextArea", () => {
beforeEach(() => {
cy.visitPage("TextArea", "Dynamic-Height");
});

it("should adjust height automatically with text content change", () => {
let initialHeight = 0;
cy.findByRole("textbox").then(($element) => {
initialHeight = $element.height();
});
cy.findByRole("textbox").focus();
cy.findByRole("textbox").type("{Enter}{Enter}{Enter}");
cy.findByRole("textbox").then(($element) => {
const finalHeight = $element.height();
expect(finalHeight).to.be.greaterThan(initialHeight);
initialHeight = finalHeight;
});
cy.findByRole("textbox").clear();
cy.findByRole("textbox").then(($element) => {
const finalHeight = $element.height();
expect(finalHeight).to.be.lessThan(initialHeight);
});
});
});
15 changes: 15 additions & 0 deletions src/components/Textarea/Textarea.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,18 @@ The Textarea component defines a multi-line text input control.
{Template.bind({})}
</Story>
</Canvas>

### Dynamic Height

<Canvas>
<Story
name="Dynamic Height"
args={{
label: "Text area that will dynamically adjust its height based on content",
defaultValue: "Ubuntu",
grow: true
}}
>
{Template.bind({})}
</Story>
</Canvas>
22 changes: 18 additions & 4 deletions src/components/Textarea/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from "classnames";
import React, { useEffect, useRef } from "react";
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
import type { TextareaHTMLAttributes, ReactNode } from "react";

import Field from "../Field";
Expand Down Expand Up @@ -90,13 +90,25 @@ const Textarea = ({
const validationId = useId();
const helpId = useId();
const hasError = !!error;
const [innerValue, setInnervalue] = useState(props.defaultValue);

useEffect(() => {
if (takeFocus) {
textareaRef.current.focus();
}
}, [takeFocus]);

useLayoutEffect(() => {
if (grow) {
const textArea = textareaRef.current;
if (textArea) {
textArea.style.height = "0px";
const scrollHeight = textArea.scrollHeight;
textArea.style.height = `${scrollHeight}px`;
}
}
}, [textareaRef, grow, innerValue, props.value]);

return (
<Field
caution={caution}
Expand All @@ -122,9 +134,10 @@ const Textarea = ({
id={id}
onKeyUp={(evt) => {
onKeyUp && onKeyUp(evt);
if (grow) {
evt.currentTarget.style.height =
evt.currentTarget.scrollHeight + "px";
}}
onChange={(evt) => {
if (!props.value) {
setInnervalue(evt.target.value);
}
}}
ref={textareaRef}
Expand All @@ -139,6 +152,7 @@ const Textarea = ({
style
}
{...props}
value={props.value || innerValue}
/>
</Field>
);
Expand Down

0 comments on commit b27d6e9

Please sign in to comment.