Skip to content

Commit

Permalink
fix(TextArea): first render is sometimes leaking out of the page (#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
aversini authored Sep 6, 2024
1 parent f183b5b commit 745f37c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
31 changes: 31 additions & 0 deletions packages/documentation/src/Form/TextArea.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Story } from "@ladle/react";
import { Button } from "@versini/ui-components";
import { TextArea } from "@versini/ui-form";
import { ThemeProvider } from "@versini/ui-system";
import { useEffect, useState } from "react";

const customTheme = {
"--av-copy-light": "#403c3a",
Expand Down Expand Up @@ -108,3 +109,33 @@ CustomTheme.args = {
),
helperText: "Powered by the sun",
};

export const Controlled: Story<any> = (args) => {
const [value, setValue] = useState(
"Charlotte, North Carolina, United States of America, Lorem Ipsum Dolor Sit Amet",
);

return (
<div className="h-full">
<form noValidate>
<div className="flex gap-2">
<TextArea
{...args}
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</div>
</form>
</div>
);
};
Controlled.args = {
rightElement: (
<Button mode="light" noBorder>
Send
</Button>
),
helperText: "Powered by the sun",
};
30 changes: 19 additions & 11 deletions packages/ui-form/src/components/TextArea/TextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { useMergeRefs, useUncontrolled, useUniqueId } from "@versini/ui-hooks";
import {
useMergeRefs,
useResizeObserver,
useUncontrolled,
useUniqueId,
} from "@versini/ui-hooks";
import React, { useLayoutEffect, useRef, useState } from "react";
import { adjustLabelAndHelperText, getTextAreaClasses } from "./utilities";

Expand Down Expand Up @@ -42,7 +47,7 @@ export const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
) => {
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const mergedTextAreaRef = useMergeRefs([ref, textAreaRef]);
const rightElementRef = useRef<HTMLDivElement>(null);
const [rightElementRef, rect] = useResizeObserver<HTMLDivElement>();
const textAreaHeightRef = useRef<number>(80);
const labelOffsetRef = useRef<number>(-25);
const labelRef = useRef<HTMLLabelElement>(null);
Expand Down Expand Up @@ -109,17 +114,20 @@ export const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
* that the text in the textarea does not overlap with the
* rightElement.
*/
/* v8 ignore next 10 */
/* c8 ignore start - ResizeObserver is tough to test... */
useLayoutEffect(() => {
if (
!raw &&
rightElement &&
rightElementRef.current &&
rightElementRef.current.offsetWidth > 0
) {
setTextAreaPaddingRight(rightElementRef.current.offsetWidth + 18 + 10);
if (rect && rect.width) {
/**
* - rect.width is the width of the right element (Button, Icon, etc.)
* - The main input field has default left/right paddings of
* 16px (px-4) + 2px border (border-2) = 18px
* - We add 10px to the right padding to give some space between the right
* element and the input field.
*/
setTextAreaPaddingRight(rect.width + 18 + 10);
}
}, [rightElement, raw]);
}, [rect]);
/* c8 ignore end */

/**
* This effect is used to resize the textarea based
Expand Down

0 comments on commit 745f37c

Please sign in to comment.