textarea.tsx
Overview
textarea.tsx defines two React components, Textarea and BlurTextarea, that provide enhanced textarea input fields with advanced features such as automatic height adjustment and controlled blur-based updates. These components improve user experience by dynamically resizing to fit content and by controlling when changes propagate to parent components.
Textarea: A flexible textarea component supporting optional auto-sizing (auto height adjustment) with customizable minimum and maximum rows.
BlurTextarea: A wrapper around
Textareawhich manages internal state and only triggersonChangewhen the textarea loses focus (on blur), useful for performance optimization or deferred updates.
Components and Functions
Textarea
A forward-ref React component that renders a textarea input with optional auto-sizing behavior.
Props
Extends all standard HTML <textarea> attributes with an additional optional autoSize prop.
interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'autoSize'> {
autoSize?: {
minRows?: number; // Minimum visible rows for the textarea
maxRows?: number; // Maximum visible rows for the textarea
};
}
className?: string— Additional CSS classes to style the textarea.autoSize?: { minRows?: number; maxRows?: number }— Enables automatic height adjustment based on content with optional row constraints.Other standard
<textarea>props (e.g.,value,onChange,placeholder, etc.).
Behavior
When
autoSizeis provided, the component dynamically adjusts the textarea's height to fit its content between specified minimum and maximum rows.Uses a hidden calculation of line height via
window.getComputedStyleto determine height boundaries.The height adjustment runs on each render via
useEffectand usesrequestAnimationFramefor smooth UI updates.Forwards ref to the underlying
<textarea>element.
Implementation Details
getLineHeight(element)calculates pixel height of a single line inside the textarea.adjustHeight()recalculates and sets the textarea height, clamping it tomaxRows * lineHeight.Handles
refforwarding to provide parent components access to the DOM node.
Usage Example
<Textarea
autoSize={{ minRows: 2, maxRows: 6 }}
placeholder="Type your message..."
/>
BlurTextarea
A forward-ref React component that wraps the Textarea component to provide controlled input behavior with deferred onChange invocation.
Props
Extends standard textarea props and requires:
value: string | readonly string[] | number | undefined— The controlled value of the textarea.onChange(value: Value): void— Callback invoked only on blur, not on every keystroke.
Behavior
Manages internal state
valto reflect current textarea content.Updates internal state on every keystroke (
onChange).Calls the external
onChangecallback only when the textarea loses focus (onBlur).Updates internal state when the
valueprop changes externally.
Usage Example
<BlurTextarea
value={message}
onChange={(newVal) => setMessage(newVal)}
placeholder="Enter text and blur to save"
/>
Important Implementation Details and Algorithms
Dynamic Height Adjustment:
The core logic is inadjustHeight(), which:Resets the height to
'auto'to shrink before measuring.Measures
scrollHeightof the textarea (the full content height).Sets the height to the smaller of the content height or the maximum allowed height based on
maxRows.Uses
requestAnimationFrameto avoid layout thrashing and to synchronize with browser repaint cycles.
Line Height Calculation:
Extracted from computed styles to ensure accurate sizing regardless of font or CSS changes.Ref Forwarding:
Both components correctly forward refs, supporting imperative access to the textarea DOM nodes.Blur-based Change Propagation:
BlurTextareareduces the frequency of updates to parent components by only notifying changes on blur, which can improve performance when typing rapidly or when updates trigger expensive operations.
Interactions with Other Parts of the System
Imports
cnutility from@/lib/utilsfor conditional className concatenation.Designed as reusable input components, likely integrated into forms or UI modules requiring multiline text input.
Textareacan be used standalone or as a base for controlled input components likeBlurTextarea.Since it uses standard HTML textarea attributes, it fits seamlessly into React forms and controlled/uncontrolled input scenarios.
The styling classes refer to a design system or CSS framework (e.g., utility classes for borders, focus ring, disabled state), ensuring consistent UI appearance across the app.
Visual Diagram
componentDiagram
component Textarea {
+props: TextareaProps
+ref: React.Ref<HTMLTextAreaElement>
-textareaRef: React.RefObject<HTMLTextAreaElement>
-getLineHeight(element: HTMLElement): number
-adjustHeight(): void
+render(): JSX.Element
}
component BlurTextarea {
+props: ComponentProps<'textarea'> & { value: Value; onChange(value: Value): void }
+ref: React.Ref<HTMLTextAreaElement>
-val: Value (state)
-handleChange(e: ChangeEvent<HTMLTextAreaElement>): void
-handleBlur(e: FocusEvent<HTMLTextAreaElement>): void
+render(): JSX.Element
}
BlurTextarea --> Textarea : uses
Summary
textarea.tsxprovides advanced textarea components with dynamic height and controlled blur-update features.Textareasupports auto-sizing to improve UX for variable-length inputs.BlurTextareadefers change notification until blur, useful for performance-sensitive scenarios.Both components are forward-ref compatible and styled consistently with utility-based CSS.
Implements an efficient algorithm for height adjustment based on line height and content scroll height.
This file is a foundational UI building block for handling multiline text input with enhanced control and styling in React applications.