Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/textarea-auto-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Textarea: Add an `autoSize` option that allows the field to grow with its content
5 changes: 5 additions & 0 deletions packages/react/src/Textarea/TextArea.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
resize: vertical;
}

.TextArea[data-auto-size='true'] {
min-height: 1lh;
field-sizing: content;
}

.TextArea:disabled {
resize: none;
}
Expand Down
8 changes: 7 additions & 1 deletion packages/react/src/Textarea/Textarea.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@
"defaultValue": "'both'",
"description": "Changes the resize behavior"
},
{
"name": "autoSize",
"type": "boolean",
"defaultValue": "false",
"description": "Allows the textarea to grow to fit its content"
},
{
"name": "characterLimit",
"type": "number",
Expand Down Expand Up @@ -110,4 +116,4 @@
}
],
"subcomponents": []
}
}
9 changes: 9 additions & 0 deletions packages/react/src/Textarea/Textarea.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ export const CustomResizeBehavior = () => (
</Stack>
)

export const AutoSize = () => (
<form>
<FormControl>
<FormControl.Label>Automatically growing textarea</FormControl.Label>
<Textarea autoSize />
</FormControl>
</form>
)

export const MinimumHeight = () => (
<form>
<FormControl>
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/Textarea/Textarea.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Playground.args = {
block: false,
cols: DEFAULT_TEXTAREA_COLS,
disabled: false,
autoSize: false,
resize: DEFAULT_TEXTAREA_RESIZE,
contrast: false,
rows: DEFAULT_TEXTAREA_ROWS,
Expand All @@ -45,6 +46,9 @@ Playground.argTypes = {
disabled: {
control: {type: 'boolean'},
},
autoSize: {
control: {type: 'boolean'},
},
resize: {
options: ['none', 'both', 'horizontal', 'vertical'],
control: {type: 'radio'},
Expand Down
11 changes: 11 additions & 0 deletions packages/react/src/Textarea/Textarea.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ describe('Textarea', () => {
expect(hasResizeDeclaration).toBe(true)
})

it('enables automatic sizing without changing resize behavior', () => {
render(<Textarea autoSize resize="vertical" />)
const textareaElement = screen.getByRole('textbox')

expect(textareaElement).toHaveAttribute('data-auto-size', 'true')
expect(textareaElement).toHaveAttribute('data-resize', 'vertical')

const rules = getCSSRules(`.${classes.TextArea}[data-auto-size="true"]`)
expect(rules.some(rule => rule.style.minHeight === '1lh' && rule.style.fieldSizing === 'content')).toBe(true)
Comment thread
HiroAgustin marked this conversation as resolved.
Outdated
})

it('renders a value in the textarea', () => {
const mockValue = 'mock value'
const onChange = vi.fn()
Expand Down
6 changes: 6 additions & 0 deletions packages/react/src/Textarea/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export type TextareaProps = {
* Allows resizing of the textarea
*/
resize?: 'none' | 'both' | 'horizontal' | 'vertical'
/**
* Allows the textarea to grow to fit its content
*/
autoSize?: boolean
/**
* apply a high contrast color to background
*/
Expand Down Expand Up @@ -74,6 +78,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
rows = DEFAULT_TEXTAREA_ROWS,
cols = DEFAULT_TEXTAREA_COLS,
resize = DEFAULT_TEXTAREA_RESIZE,
autoSize,
block,
contrast,
className,
Expand Down Expand Up @@ -133,6 +138,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
defaultValue={defaultValue}
data-component="Textarea"
data-resize={resize}
data-auto-size={autoSize || undefined}
aria-required={required}
aria-invalid={isValid === 'error' ? 'true' : 'false'}
ref={ref}
Expand Down
Loading