Skip to content

Refactor/text area v2#1336

Merged
vinitkhandal717 merged 10 commits intodevfrom
refactor/TextAreaV2
Apr 16, 2026
Merged

Refactor/text area v2#1336
vinitkhandal717 merged 10 commits intodevfrom
refactor/TextAreaV2

Conversation

@deepakoram-juspay
Copy link
Copy Markdown
Collaborator

@deepakoram-juspay deepakoram-juspay commented Apr 8, 2026

Screen.Recording.2026-04-08.at.9.00.56.PM.mov

Summary

TextAreaV2 added

Issue Ticket

Closes #1335

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Inputs V2 multiline textarea (TextAreaV2) to the Blend design system, wiring it into the theme token infrastructure and providing Storybook, site demos, and automated tests.

Changes:

  • Introduces TextAreaV2 component with responsive light/dark token sets and theme registration (TEXT_AREA_V2).
  • Adds unit + accessibility tests (including axe) and Storybook stories for TextAreaV2.
  • Updates site demo navigation to include a new TextAreaV2 demo and sets it as the default active demo.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/blend/lib/context/useComponentToken.ts Registers TEXT_AREA_V2 in token lookup.
packages/blend/lib/context/ThemeContext.tsx Adds TEXT_AREA_V2 to ComponentTokenType and default theme token initialization.
packages/blend/lib/context/initComponentTokens.ts Initializes TEXT_AREA_V2 tokens when not provided by consumers.
packages/blend/lib/components/InputsV2/TextAreaV2/TextAreaV2.types.ts Defines public props for TextAreaV2.
packages/blend/lib/components/InputsV2/TextAreaV2/TextAreaV2.tsx Implements the TextAreaV2 component using Inputs V2 label/footer utilities and PrimitiveTextarea.
packages/blend/lib/components/InputsV2/TextAreaV2/TextAreaV2.tokens.ts Defines token types + token getter selecting light/dark.
packages/blend/lib/components/InputsV2/TextAreaV2/TextAreaV2.light.tokens.ts Light theme token values for TextAreaV2.
packages/blend/lib/components/InputsV2/TextAreaV2/TextAreaV2.dark.tokens.ts Dark theme token values for TextAreaV2.
packages/blend/lib/components/InputsV2/TextAreaV2/index.tsx Barrel exports for TextAreaV2.
packages/blend/lib/components/InputsV2/MultiValueInputV2/MultiValueInputV2.tsx Adds displayName (debuggability/devtools).
packages/blend/Design-docs/TextArea/TextAreaDoc.md Design/behavior documentation for TextAreaV2.
packages/blend/tests/components/TextAreaV2/TextAreaV2.test.tsx Functional/unit tests for rendering, props, events, ref forwarding.
packages/blend/tests/components/TextAreaV2/TextAreaV2.accessibility.test.tsx Accessibility tests using axe + ARIA assertions.
apps/storybook/stories/components/TextAreaV2/TextAreaV2.stories.tsx Storybook stories + docs for TextAreaV2.
apps/site/src/demos/TextAreaV2Demo.tsx Adds a dedicated site demo page for TextAreaV2.
apps/site/src/demos/SidebarDemo.tsx Adds TextAreaV2 to the site demo sidebar and switches default selection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to +110
{!isSmallScreen && (
<InputLabelsV2
tokens={textAreaTokens.topContainer}
label={label}
sublabel={sublabel}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the sm breakpoint the label stack is not rendered (!isSmallScreen), and the textarea placeholder is also set to an empty string. That leaves the <textarea> without an accessible name on small screens, which is a WCAG violation. Consider keeping an accessible label by either rendering the label visually-hidden on sm, or setting aria-label/aria-labelledby from label when static labels are hidden.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

sublabel?: string
hintText?: string
helpIconHintText?: string
helpIconText?: string
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helpIconText is declared in TextAreaV2Props, but TextAreaV2 does not destructure or use it. If a consumer passes helpIconText, it will end up in ...rest and be forwarded to the DOM <textarea> as an invalid attribute (React will warn). Either remove helpIconText from the public props, or explicitly consume it (e.g., map it to InputLabelsV2’s helpIconText).

Suggested change
helpIconText?: string

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment on lines +21 to +22
resize?: 'none' | 'both' | 'horizontal' | 'vertical' | 'block' | 'inline'
wrap?: CSSObject['whiteSpace']
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap is typed as CSSObject['whiteSpace'], but it is passed through as the native <textarea wrap> attribute. Values like "pre" (used in the site demo) are not valid for the HTML wrap attribute (valid values are typically "soft"/"hard"). Align the prop type/behavior: either change the prop to match the native attribute type, or introduce a separate styling prop (e.g., whiteSpace) and apply it via styles instead of the DOM attribute.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@@ -0,0 +1,3 @@
export { default as TextAreaV2 } from './TextAreaV2.tsx'
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exporting with an explicit .tsx extension is inconsistent with the other component barrel files in this repo (e.g. InputsV2/MultiValueInputV2/index.ts). Prefer export { default as TextAreaV2 } from './TextAreaV2' to avoid resolver/config edge cases and keep conventions consistent.

Suggested change
export { default as TextAreaV2 } from './TextAreaV2.tsx'
export { default as TextAreaV2 } from './TextAreaV2'

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +437 to +444
<div
className="p-4 border rounded cursor-pointer hover:bg-gray-50"
onClick={() => {
addSnackbar({
header: 'Demo clicked!',
})
}}
>
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The demo wraps TextAreaV2 in a clickable container that always fires addSnackbar(...). Because events bubble, clicking inside the textarea will also trigger the snackbar, which makes the field hard to interact with. Consider guarding the handler (e.g., only trigger when e.target === e.currentTarget) or stopping propagation from the textarea.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to +118
{!isSmallScreen && (
<InputLabelsV2
tokens={textAreaTokens.topContainer}
label={label}
sublabel={sublabel}
helpIconText={helpIconHintText}
inputId={textareaId}
name={name}
required={required || false}
size={InputSizeV2.SM}
state={labelState}
/>
)}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the sm breakpoint the component does not render InputLabelsV2, and it also clears the placeholder. If a consumer passes label but does not also pass an aria-label/aria-labelledby via rest, the <textarea> ends up without an accessible name (WCAG 3.3.2 / axe will flag this). Consider always providing an accessible name when label is set (e.g., set aria-label from label when labels are hidden, or render a visually-hidden label).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment thread apps/site/src/demos/TextAreaV2Demo.tsx Outdated
placeholder="Paste your code here..."
rows={8}
resize="both"
wrap="pre"
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap="pre" is not a valid value for the native <textarea wrap> attribute (valid values are typically hard/soft). With the current TextAreaV2 implementation this prop is forwarded to the DOM attribute, so this demo example won’t behave as intended. Update the demo to use valid wrap values, or adjust the component API to control CSS white-space instead of the HTML wrap attribute.

Suggested change
wrap="pre"
wrap="soft"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap removed

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +124 to +133
inputId={textareaId}
isInputFocusedOrWithValue={inputFocusedOrWithValue}
topPadding={paddingX}
leftPadding={paddingX}
tokens={{
placeholder: ic.placeholder,
required: textAreaTokens.topContainer.required,
}}
size={size}
state={labelState}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FloatingLabelsV2 expects topPadding to be the textarea's top padding and leftPadding to be the left padding. Here topPadding is set to paddingX (derived from right padding) and leftPadding is also paddingX, which will misplace the floating label if top/left/right paddings ever diverge. Consider deriving paddingTop and paddingLeft separately from ic.padding.top[size] / ic.padding.left[size] and pass those into FloatingLabelsV2 (and keep paddingX only for the textarea’s horizontal padding if desired).

Copilot uses AI. Check for mistakes.
Comment on lines +208 to +219
render: function WithErrorStory() {
const [value, setValue] = useState('Too short')
return (
<TextAreaV2
label="Bio"
placeholder="Tell us about yourself"
value={value}
onChange={(e) => setValue(e.target.value)}
error
errorMessage="Please enter at least 50 characters."
/>
)
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Storybook stories are using the old TextArea API (error boolean + errorMessage string). TextAreaV2 in this PR takes error as an object ({ show, message? }), so these stories won’t type-check and won’t actually render the error state correctly. Update the story to pass error={{ show: true, message: ... }} and remove errorMessage usage.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment on lines +124 to +175
},
disabled: {
control: { type: 'boolean' },
description: 'Disables the textarea',
table: { type: { summary: 'boolean' }, category: 'State' },
},
error: {
control: { type: 'boolean' },
description: 'Validation error state (use with errorMessage)',
table: { type: { summary: 'boolean' }, category: 'Validation' },
},
errorMessage: {
control: { type: 'text' },
description: 'Error message shown when error is true',
table: { type: { summary: 'string' }, category: 'Validation' },
},
autoFocus: {
control: { type: 'boolean' },
description: 'Focus the textarea on mount',
table: { type: { summary: 'boolean' }, category: 'Behavior' },
},
onChange: {
action: 'changed',
table: {
type: {
summary:
'(e: React.ChangeEvent<HTMLTextAreaElement>) => void',
},
category: 'Events',
},
},
onFocus: {
action: 'focused',
table: {
type: {
summary:
'(e: React.FocusEvent<HTMLTextAreaElement>) => void',
},
category: 'Events',
},
},
onBlur: {
action: 'blurred',
table: {
type: {
summary:
'(e: React.FocusEvent<HTMLTextAreaElement>) => void',
},
category: 'Events',
},
},
},
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

argTypes documents and controls error and errorMessage, but TextAreaV2 does not expose those props (it uses error: { show, message? }). Keeping these argTypes will mislead consumers and can break autogenerated docs/controls. Align the argTypes with the actual component API (e.g., a nested error.show / error.message control, or a single object control) and update the docs text accordingly.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment on lines +437 to +452
<div
className="p-4 border rounded cursor-pointer hover:bg-gray-50"
onClick={() => {
addSnackbar({
header: 'Demo clicked!',
})
}}
>
<TextAreaV2
label="Click the container"
value=""
onChange={() => {}}
placeholder="Click outside the text area"
/>
</div>
</div>
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This demo wraps TextAreaV2 in a container with an unconditional onClick that calls addSnackbar(...). Clicking inside the textarea will still bubble a click event and trigger the snackbar, making the field hard to interact with. Consider guarding the handler (e.g., only fire when e.target === e.currentTarget) or preventing click bubbling from the textarea (either here or via an onClick handler on TextAreaV2).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handled in TextAreaV2 component

Comment on lines +12 to +13
rows?: number
cols?: number
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we have rows and cols in textarea ideally this prop should not be there

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

row is needed to control the number of row should acquire the textArea height
Screenshot 2026-04-14 at 6 49 14 PM
Screenshot 2026-04-14 at 6 49 28 PM

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be control by height not rows also cols prop is no use

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Col is removed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each “row” follows the textarea’s line box: it uses the element’s font-size, line-height (from your styles, inheritance, or the browser default), and related font metrics—so one row ≈ one line of text at that typography,
So, we don't have to calculate the height and handle by ourself "row" prop is doing it automatically.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still this is unnecessary just pass max height and give each row a fixed height based on text font size and line height

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

paddingX={paddingX}
paddingTop={
isSmallScreen && inputFocusedOrWithValue
? paddingY + 14
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove this hardcode value

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +54 to +82
const generatedId = useId()
const textareaId = providedId || generatedId
const { errorId, hintId } = generateAccessibilityIds(textareaId)

const ariaDescribedBy = useMemo(
() =>
[
hintText && !error.show ? hintId : null,
error.show && error.message ? errorId : null,
]
.filter(Boolean)
.join(' ') || undefined,
[hintText, error.show, error.message, hintId, errorId]
)

const labelState = useMemo((): InputStateV2 => {
if (disabled) return InputStateV2.DISABLED
if (error.show) return InputStateV2.ERROR
if (isFocused) return InputStateV2.FOCUS
return InputStateV2.DEFAULT
}, [disabled, error.show, isFocused])

const inputFocusedOrWithValue = isFocused || value.length > 0

const paddingX = toPixels(ic.padding.right[size])
const paddingY = toPixels(ic.padding.top[size])

const setTextAreaRef = (node: HTMLTextAreaElement | null) => {
setExternalRef(ref as AnyRef<HTMLTextAreaElement>, node)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to utils or use common function

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import type { InputSizeV2, InputStateV2 } from '../../inputV2.types'
import { addPxToValue } from '../../../../global-utils/GlobalUtils'
import type { FloatingLabelsV2Tokens } from '../../inputV2.tokens'
import { CSSObject } from 'styled-components'
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSSObject is only used for a prop type (backgroundColor?: CSSObject['backgroundColor']). Import it as a type-only import (import type { CSSObject } ...) to avoid an unnecessary runtime import when TS/ESLint settings preserve value imports.

Suggested change
import { CSSObject } from 'styled-components'
import type { CSSObject } from 'styled-components'

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/>
)}
<PrimitiveTextarea
{...filteredRest}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filteredRest is spread onto PrimitiveTextarea. Because TextAreaV2Props currently includes non-DOM props like helpIconText (and the component doesn’t destructure them), those props can leak into the rendered <textarea> as invalid attributes. Ensure all non-native props are destructured/consumed before spreading filteredRest, or extend filterBlockedProps/a local omit list for this component.

Suggested change
{...filteredRest}
{...(({
helpIconText: _helpIconText,
helpIconHintText: _helpIconHintText,
...safeFilteredRest
}) => safeFilteredRest)(filteredRest)}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### 4. Small viewport: static labels off, floating label + padding

**Decision**: When **`isSmallScreen`**, **`InputLabelsV2`** is not rendered. If **`label`** is set, **`FloatingLabelsV2`** is shown. Placeholder is **`''`**. When the user focuses or the value is non-empty, top padding increases by **14px** and bottom padding goes to **0** to make room for the floated label.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc states that on small screens the top padding increases by 14px, but the implementation (getTextAreaInputPadding) increases padding by adding the base top padding again (i.e., it doubles whatever the token value is). Update the documentation to describe the token-based behavior (or adjust the implementation if a fixed +14px is actually required).

Suggested change
**Decision**: When **`isSmallScreen`**, **`InputLabelsV2`** is not rendered. If **`label`** is set, **`FloatingLabelsV2`** is shown. Placeholder is **`''`**. When the user focuses or the value is non-empty, top padding increases by **14px** and bottom padding goes to **0** to make room for the floated label.
**Decision**: When **`isSmallScreen`**, **`InputLabelsV2`** is not rendered. If **`label`** is set, **`FloatingLabelsV2`** is shown. Placeholder is **`''`**. When the user focuses or the value is non-empty, top padding increases by adding the current base top padding again (that is, the top padding is token-driven and effectively doubles for the active size), and bottom padding goes to **0** to make room for the floated label.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

sublabel?: string
hintText?: string
helpIconHintText?: string
helpIconText?: string
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation lists helpIconText?: string as a prop, but the implementation uses helpIconHintText and does not consume helpIconText. Update the doc to reflect the actual public API to avoid consumers passing unsupported props.

Suggested change
helpIconText?: string

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helpIconHintText removed

Comment on lines +26 to +35
component: `
Multi-line text field (V2) using \`TEXT_AREA_V2\` tokens, \`InputLabelsV2\`, and \`InputFooterV2\` — same Inputs V2 patterns as \`TextInputV2\` (no size variants or left/right slots).

## Features
- Label, sublabel, hint text, and optional help hint on the label (\`helpIconHintText\`)
- \`error: { show, message? }\`, \`required\`, \`disabled\`
- \`rows\`, \`resize\`, \`wrap\` — passed to the native \`<textarea>\`
- On small breakpoints, static labels are hidden and placeholder is cleared
- Forwarded \`ref\` attaches to the \`<textarea>\` element
- \`filterBlockedProps\` strips \`className\` / \`style\` from spread rest
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Story docs mention “no size variants”, but TextAreaV2 does expose a size?: InputSizeV2 prop. This is misleading for consumers and Storybook autogenerated docs. Update the description (and optionally add an argTypes.size control) to match the component API.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Comment on lines +15 to +23
hintText?: string
helpIconHintText?: string
helpIconText?: string
required?: boolean
error?: {
show: boolean
message?: string
}
resize?: 'none' | 'both' | 'horizontal' | 'vertical' | 'block' | 'inline'
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helpIconText is declared on TextAreaV2Props but TextAreaV2 never consumes it. If a consumer passes it, it will be forwarded to the underlying <textarea> via ...rest (and filterBlockedProps won’t remove it), causing an invalid DOM attribute / React warning. Remove helpIconText from the public props, or explicitly destructure it and map it to InputLabelsV2 (or otherwise prevent it from reaching the DOM).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced 'helpIconHintText' with 'helpIconText'

Comment on lines +194 to +195
border: ic.border[borderFocus],
boxShadow: FOCUS_RING_STYLES.boxShadow,
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FOCUS_RING_STYLES includes both boxShadow and backgroundColor, but the textarea _focus styles only apply the boxShadow. This makes TextAreaV2 focus visuals diverge from other InputsV2 (e.g. TextInputV2), and also leaves TRANSITION’s background-color portion unused. Consider spreading FOCUS_RING_STYLES (or at least applying its backgroundColor when not in error state) in the _focus style block for consistency.

Suggested change
border: ic.border[borderFocus],
boxShadow: FOCUS_RING_STYLES.boxShadow,
...FOCUS_RING_STYLES,
border: ic.border[borderFocus],
backgroundColor: error.show
? ic.backgroundColor[bgDefault]
: FOCUS_RING_STYLES.backgroundColor,

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10 to +14
export type TextAreaTokensType = {
gap: CSSObject['gap']
topContainer: InputLabelsV2Tokens
inputContainer: {
gap: CSSObject['gap']
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextAreaV2.tokens.ts exports TextAreaTokensType, which collides in name with the existing legacy Inputs/TextArea/textarea.token.ts export. Since this is a V2 component, consider renaming this to TextAreaV2TokensType to avoid confusing imports and accidental mixing of V1/V2 token types.

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +70
export type ResponsiveTextAreaTokens = {
[key in keyof BreakpointType]: TextAreaTokensType
}

export type ResponsiveTextAreaV2Tokens = ResponsiveTextAreaTokens

export const getTextAreaV2Tokens = (
foundationToken: FoundationTokenType,
theme: Theme | string = Theme.LIGHT
): ResponsiveTextAreaTokens => {
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file exports ResponsiveTextAreaTokens and then aliases ResponsiveTextAreaV2Tokens = ResponsiveTextAreaTokens. The name ResponsiveTextAreaTokens already exists for the legacy TextArea tokens, so re-exporting it here increases the chance of import collisions. Prefer defining/exporting only ResponsiveTextAreaV2Tokens (and have getTextAreaV2Tokens return that type) to keep V2 naming consistent with other InputsV2 token files.

Suggested change
export type ResponsiveTextAreaTokens = {
[key in keyof BreakpointType]: TextAreaTokensType
}
export type ResponsiveTextAreaV2Tokens = ResponsiveTextAreaTokens
export const getTextAreaV2Tokens = (
foundationToken: FoundationTokenType,
theme: Theme | string = Theme.LIGHT
): ResponsiveTextAreaTokens => {
export type ResponsiveTextAreaV2Tokens = {
[key in keyof BreakpointType]: TextAreaTokensType
}
export const getTextAreaV2Tokens = (
foundationToken: FoundationTokenType,
theme: Theme | string = Theme.LIGHT
): ResponsiveTextAreaV2Tokens => {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Multi-line text field (V2) using \`TEXT_AREA_V2\` tokens, \`InputLabelsV2\`, and \`InputFooterV2\` — same Inputs V2 patterns as \`TextInputV2\` (no size variants or left/right slots).

## Features
- Label, sublabel, hint text, and optional help hint on the label (\`helpIconHintText\`)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Story docs mention helpIconHintText, but TextAreaV2’s public prop is helpIconText (and the component uses helpIconText). This will mislead consumers and docs/autodocs. Update the description string to reference helpIconText (or whichever prop is actually supported).

Suggested change
- Label, sublabel, hint text, and optional help hint on the label (\`helpIconHintText\`)
- Label, sublabel, hint text, and optional help hint on the label (\`helpIconText\`)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

export { default as TextAreaV2 } from './TextAreaV2'
export * from './TextAreaV2.types'
export * from './TextAreaV2.tokens'
export * from './utils'
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export * from './utils' makes internal helpers (e.g. omit/aria helper functions) part of the public TextAreaV2 module surface. Other InputsV2 barrels (e.g. TextInputV2, NumberInputV2) only export the component, types, and tokens; consider removing this export or moving it behind an explicitly-internal path to avoid committing to these utils as public API.

Suggested change
export * from './utils'

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vinitkhandal717 vinitkhandal717 merged commit fac0cda into dev Apr 16, 2026
12 checks passed
@vinitkhandal717 vinitkhandal717 deleted the refactor/TextAreaV2 branch April 16, 2026 04:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TextArea refactor

3 participants