From 3ec44e54d2a08267a96403d3df0529d1002fcef0 Mon Sep 17 00:00:00 2001
From: Danny White <3104761+dnywh@users.noreply.github.com>
Date: Thu, 24 Sep 2026 17:10:28 +1000
Subject: [PATCH] fix(ui): restore grouped textarea top padding (#50843)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Problem
- Grouped textareas render text too close to the top border. The
standalone `Textarea` retains its normal top padding.
- `InputGroupTextarea` has overridden the inner textarea with `py-0`
since #44282 on 31 March 2026. The group initially supplied `py-2`;
#44387 removed that outer padding later the same day, leaving no top
spacing. The override was retained during the border and surface updates
in #44690 and #48887.
- The textarea component page had no grouped textarea example, so this
difference was easy to miss.
## Solution
- Give the grouped textarea `pt-2` while retaining `pb-0` for block-end
addons. The outer group continues to own its border and focus styles.
- Add a “With addon” example to the textarea component page to keep this
composition visible.
## Review instructions
- Open `/design-system/docs/components/textarea` and find “With addon”.
Confirm its text has the same top inset as the default textarea and the
block-end addon remains below the input.
- Open `/design-system/docs/ui-patterns/forms` and find “Textarea
Multi-line text input for longer content with addon”. Confirm the text
has the same top inset as the standalone textarea example immediately
above it.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
## Summary by CodeRabbit
* **New Features**
* Added a textarea example with a supporting addon below the text field,
showing a 120-character limit.
* **Bug Fixes**
* Clicking a block-end addon now focuses its textarea as well as an
input.
* **Documentation**
* Added the textarea-with-addon example to the textarea component
documentation.
* **Style**
* Added top padding to textareas within input groups while keeping
bottom padding unchanged, adjusting spacing above entered text.
---
.../content/docs/components/textarea.mdx | 6 ++++++
.../registry/default/example/textarea-with-addon.tsx | 12 ++++++++++++
apps/design-system/registry/examples.ts | 6 ++++++
packages/ui/src/components/shadcn/ui/input-group.tsx | 6 ++++--
4 files changed, 28 insertions(+), 2 deletions(-)
create mode 100644 apps/design-system/registry/default/example/textarea-with-addon.tsx
diff --git a/apps/design-system/content/docs/components/textarea.mdx b/apps/design-system/content/docs/components/textarea.mdx
index 07b91d58963..a1ab2438d55 100644
--- a/apps/design-system/content/docs/components/textarea.mdx
+++ b/apps/design-system/content/docs/components/textarea.mdx
@@ -72,6 +72,12 @@ import { Textarea } from '@/components/ui/textarea'
+### With addon
+
+An addon places supporting content inside the same bordered field as the textarea. Wrap `InputGroupTextarea` and `InputGroupAddon` in `InputGroup`, and use `align="block-end"` to place the addon below the text.
+
+
+
### Form
diff --git a/apps/design-system/registry/default/example/textarea-with-addon.tsx b/apps/design-system/registry/default/example/textarea-with-addon.tsx
new file mode 100644
index 00000000000..079fcd559b6
--- /dev/null
+++ b/apps/design-system/registry/default/example/textarea-with-addon.tsx
@@ -0,0 +1,12 @@
+import { InputGroup, InputGroupAddon, InputGroupText, InputGroupTextarea } from 'ui'
+
+export default function TextareaWithAddon() {
+ return (
+
+
+
+ 120 character limit
+
+
+ )
+}
diff --git a/apps/design-system/registry/examples.ts b/apps/design-system/registry/examples.ts
index e1baf7235da..13c8741b839 100644
--- a/apps/design-system/registry/examples.ts
+++ b/apps/design-system/registry/examples.ts
@@ -1021,6 +1021,12 @@ export const examples: Registry = [
registryDependencies: ['textarea', 'form'],
files: ['example/textarea-form.tsx'],
},
+ {
+ name: 'textarea-with-addon',
+ type: 'components:example',
+ registryDependencies: ['textarea', 'input-group'],
+ files: ['example/textarea-with-addon.tsx'],
+ },
{
name: 'textarea-with-button',
type: 'components:example',
diff --git a/packages/ui/src/components/shadcn/ui/input-group.tsx b/packages/ui/src/components/shadcn/ui/input-group.tsx
index d0506aa2216..e2b7411330d 100644
--- a/packages/ui/src/components/shadcn/ui/input-group.tsx
+++ b/packages/ui/src/components/shadcn/ui/input-group.tsx
@@ -112,7 +112,9 @@ function InputGroupAddon({
if ((e.target as HTMLElement).closest('button')) {
return
}
- e.currentTarget.parentElement?.querySelector('input')?.focus()
+ e.currentTarget.parentElement
+ ?.querySelector('[data-slot=input-group-control]')
+ ?.focus()
}}
{...props}
/>
@@ -191,7 +193,7 @@ const InputGroupTextarea = React.forwardRef(
ref={ref}
data-slot="input-group-control"
className={cn(
- 'flex-1 resize-none rounded-none border border-transparent bg-transparent py-0 shadow-none',
+ 'flex-1 resize-none rounded-none border border-transparent bg-transparent pt-2 pb-0 shadow-none',
'hover:border-transparent focus:border-transparent focus-visible:border-transparent',
'focus-visible:ring-0 focus-visible:ring-offset-0',
'aria-[invalid=true]:border-transparent aria-[invalid=true]:bg-transparent',