Skip to content

Commit

Permalink
Merge pull request #254 from reaviz/textarea-ref-bug
Browse files Browse the repository at this point in the history
fix textarea input ref
  • Loading branch information
amcdnl authored Aug 12, 2024
2 parents c8ae8ae + 08b7a34 commit 7f6d12c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
14 changes: 13 additions & 1 deletion src/form/Textarea/Textarea.story.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { useRef } from 'react';
import { Stack } from '../../layout/Stack';
import { Textarea } from './Textarea';
import { Button } from '@/elements';

export default {
title: 'Components/Form/Textarea',
Expand Down Expand Up @@ -32,3 +33,14 @@ export const Sizes = () => (
<Textarea value="Large" size="large" />
</Stack>
);

export const OutsideFocus = () => {
const inputRef = useRef(null);

return (
<Stack direction="column">
<Button onClick={() => inputRef?.current.focus()}>Click to focus</Button>
<Textarea ref={inputRef} />
</Stack>
);
};
32 changes: 19 additions & 13 deletions src/form/Textarea/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {
FC,
import {
forwardRef,
RefObject,
useImperativeHandle,
useLayoutEffect,
useRef
} from 'react';
import TextareaAutosize, {
Expand Down Expand Up @@ -61,32 +61,37 @@ export interface TextAreaRef {
focus?: () => void;
}

export const Textarea: FC<TextareaProps & TextAreaRef> = forwardRef<
TextAreaRef,
TextareaProps
>(
export const Textarea = forwardRef<TextAreaRef, TextareaProps>(
(
{
fullWidth,
size = 'medium',
containerClassName,
className,
error,
autoFocus,
theme: customTheme,
...rest
},
ref
inputRef
) => {
const containerRef = useRef<HTMLDivElement | null>(null);
const inputRef = useRef<HTMLTextAreaElement | null>(null);
const textareaRef = useRef<HTMLTextAreaElement | null>(null);

useImperativeHandle(ref, () => ({
inputRef,
useImperativeHandle(inputRef, () => ({
textareaRef,
containerRef,
blur: () => inputRef.current?.blur(),
focus: () => inputRef.current?.focus()
blur: () => textareaRef.current?.blur(),
focus: () => textareaRef.current?.focus()
}));

useLayoutEffect(() => {
if (autoFocus) {
// Small timeout for page loading
requestAnimationFrame(() => textareaRef.current?.focus());
}
}, [autoFocus]);

const theme: TextareaTheme = useComponentTheme('textarea', customTheme);

return (
Expand All @@ -100,14 +105,15 @@ export const Textarea: FC<TextareaProps & TextAreaRef> = forwardRef<
ref={containerRef}
>
<TextareaAutosize
ref={inputRef}
ref={textareaRef}
className={twMerge(
theme.input,
fullWidth && theme.fullWidth,
rest.disabled && theme.disabled,
theme.sizes[size],
className
)}
autoFocus={autoFocus}
{...rest}
/>
</div>
Expand Down

0 comments on commit 7f6d12c

Please sign in to comment.