Repository: marigold-ui/marigold
Pull request #1964 (2022-04-04 10:20:33)

refa: Use `<Field>` in `<TextArea>` 
- rename from Textarea to TextArea!

changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: 0b01719eb406e0417f782b3e1b845aa8fc2e0b8a

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 6 packages</summary>

  | Name                       | Type  |
| -------------------------- | ----- |
| @marigold/docs             | Minor |
| @marigold/components       | Minor |
| @marigold/storybook-config | Patch |
| @marigold/theme-b2b        | Major |
| @marigold/theme-core       | Major |
| @marigold/theme-unicorn    | Major |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/marigold-ui/marigold/new/redo-textarea?filename=.changeset/mighty-beans-suffer.md&value=---%0A%22%40marigold%2Fdocs%22%3A%20patch%0A%22%40marigold%2Fcomponents%22%3A%20patch%0A%22%40marigold%2Ftheme-b2b%22%3A%20patch%0A%22%40marigold%2Ftheme-core%22%3A%20patch%0A%22%40marigold%2Ftheme-unicorn%22%3A%20patch%0A---%0A%0Arefa%3A%20Use%20%60%3CField%3E%60%20in%20%60%3CTextArea%3E%60%20%0A)



Patch:
diff --git a/.changeset/ninety-taxis-perform.md b/.changeset/ninety-taxis-perform.md
new file mode 100644
index 000000000..947ceabf9
--- /dev/null
+++ b/.changeset/ninety-taxis-perform.md
@@ -0,0 +1,8 @@
+---
+"@marigold/docs": minor
+"@marigold/components": minor
+"@marigold/theme-b2b": minor
+"@marigold/theme-core": minor
+---
+
+refa: Use `<Field>` in `<TextArea>` 
diff --git a/.changeset/wicked-chefs-guess.md b/.changeset/wicked-chefs-guess.md
new file mode 100644
index 000000000..565a322ce
--- /dev/null
+++ b/.changeset/wicked-chefs-guess.md
@@ -0,0 +1,5 @@
+---
+"@marigold/docs": patch
+---
+
+refa(docs): update mdx pages with name d-p
diff --git a/docs/content/components/dialog.mdx b/docs/content/components/dialog.mdx
index 524fa4731..f5291cddc 100644
--- a/docs/content/components/dialog.mdx
+++ b/docs/content/components/dialog.mdx
@@ -6,18 +6,20 @@ import { FigmaLink } from '../../src/components/FigmaLink';
 
 # Dialog
 
-## Description
-
 Component to display a Dialog as a reaction to an event. The Dialog could be styled via theme and should be filled with content.
 You can also add a title via title prop.
 
+```tsx onlyCode
+import { Dialog } from '@marigold/components';
+```
+
 <FigmaLink
   to={
     'https://www.figma.com/file/DFKyTGHAoDxOsUBPszLLxP/%F0%9F%8F%B5%EF%B8%8FMarigold?node-id=845%3A1095'
   }
 />
 
-## Properties
+## Props
 
 | Property                     | Type                                       | Default     |
 | :--------------------------- | :----------------------------------------- | :---------- |
@@ -27,15 +29,9 @@ You can also add a title via title prop.
 | `variant (optional)`         | `string`                                   | `__default` |
 | `backdropVariant (optional)` | `string`                                   | `backdrop`  |
 
-## Import
-
-```tsx onlyCode
-import { Dialog } from '@marigold/components';
-```
-
-## Live-Code Example
+## Example
 
-```tsx expandCode
+```tsx
 () => {
   const { state, openButtonProps, openButtonRef } = useDialogButtonProps();
   return (
@@ -63,31 +59,3 @@ import { Dialog } from '@marigold/components';
   );
 };
 ```
-
-## Usage
-
-```tsx
-() => {
-  const { state, openButtonProps, openButtonRef } = useDialogButtonProps();
-  return (
-    <>
-      <Button
-        variant="secondary"
-        size="small"
-        {...openButtonProps}
-        ref={openButtonRef}
-      >
-        Open Dialog
-      </Button>
-      {state.isOpen && (
-        <Dialog title="Dialog Title" isOpen={state.isOpen} close={state.close}>
-          <Text>
-            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum
-            dolor sit amet, consectetur adipiscing elit.
-          </Text>
-        </Dialog>
-      )}
-    </>
-  );
-};
-```
diff --git a/docs/content/components/divider.mdx b/docs/content/components/divider.mdx
index 51d423ba3..65444ed80 100644
--- a/docs/content/components/divider.mdx
+++ b/docs/content/components/divider.mdx
@@ -2,53 +2,51 @@
 title: Divider
 ---
 
-# Divider
+import { DoAndDont } from '../../src/components/DoAndDont';
 
-## Description
+# Divider
 
 A divider is a visual separator between two groups of content,
 e.g. groups of menu items or sections of a page.
 
-## Properties
+<Divider />
+
+```tsx onlyCode
+import { Divider } from '@marigold/components';
+```
+
+## Props
 
 | Property             | Type     | Default     |
 | :------------------- | :------- | :---------- |
 | `variant` (optional) | `string` | `__default` |
 
-## Import
+## Examples
 
-```tsx onlyCode
-import { Divider } from '@marigold/components';
+Standard Divider
+
+```tsx
+<Divider />
 ```
 
-## Live-Code Example
+Bold Divider
 
-```tsx expandCode
-<>
-  <Text>Brightside</Text>
-  <Divider />
-  <Text>Darkside</Text>
-</>
+```tsx
+<Divider variant="bold" />
 ```
 
-## Usage
-
-### Standard Divider
+## Divider between Text
 
 ```tsx
 <>
-  <Text>Some text</Text>
+  <Text>Dark Side</Text>
   <Divider />
-  <Text>Some other text to show regular divider</Text>
+  <Text>Bright Side</Text>
 </>
 ```
 
-### Bold Divider
+## Divider in Do & Don't component
 
-```tsx
-<>
-  <Text>Some text</Text>
-  <Divider variant="bold" />
-  <Text>Some other text to show strong divider</Text>
-</>
-```
+<DoAndDont preview={<Text>Look at the greend bold Divider below</Text>}>
+  Example to show how Divider is used in Do & Don't component
+</DoAndDont>
diff --git a/docs/content/components/icon.mdx b/docs/content/components/icon.mdx
index 0758cc272..e9a2b1fd0 100644
--- a/docs/content/components/icon.mdx
+++ b/docs/content/components/icon.mdx
@@ -4,9 +4,18 @@ title: Icon
 
 # Icon
 
-## Installation
+With the Icon component you can render one of the [Marigold Icons](../../foundation/icons).
+By adding the `size` prop you can change to another size. `24` is the default size.
+The `fill` prop is the second attribute and per default `currentcolor`.
 
-### 1. React Icon component:
+<Inline space="small">
+  <DesignTicket />
+  <Ticket />
+  <TicketInsurance />
+  <Resale />
+</Inline>
+
+### React Icon component
 
 Marigold Icons have a separate package to install.
 The first option is to install the package and use the Icons like other React components and as in the code example below.
@@ -20,44 +29,30 @@ npm install @marigold/icons --save
 yarn add @marigold/icons
 ```
 
-### 2. HTML SVG Element
-
-The second option is to go to [Marigold Icons](../../foundation/icons) and click on an Icon in the list to copy them as `<svg>` Element
+```tsx onlyCode
+import { DesignTicket } from '@marigold/icons';
+```
 
-## Description
+### HTML SVG Element
 
-With the Icon component you can render one of the [Marigold Icons](../../foundation/icons).
-By adding the `size` prop you can change to another size. `24` is the default size.
-The `fill` prop is the second attribute and per default `currentcolor`.
+The second option is to go to [Marigold Icons](../../foundation/icons) and click on an Icon in the list to copy them as `<svg>` Element
 
-## Properties
+## Props
 
 | Property | Type     | Default          |
 | :------- | :------- | :--------------- |
 | `size`   | `number` | `24`             |
 | `fill`   | `string` | `'currentcolor'` |
 
-## Import
-
-```tsx onlyCode
-import { DesignTicket } from '@marigold/icons';
-```
-
-## Live-Code Example
-
-```tsx expandCode
-<DesignTicket />
-```
-
-## Usage
+## Examples
 
-### size prop
+Icon size
 
 ```tsx
 <DesignTicket size={40} />
 ```
 
-### fill prop
+Icon color fill
 
 ```tsx
 <DesignTicket fill="red" />
diff --git a/docs/content/components/image.mdx b/docs/content/components/image.mdx
index 2b9ec0880..f9c9c0f2e 100644
--- a/docs/content/components/image.mdx
+++ b/docs/content/components/image.mdx
@@ -4,23 +4,19 @@ title: Image
 
 # Image
 
-## Description
+With the Image component you can render an image element.
+The variant can be added with the variant prop. The default variant is `fullWidth`. You can also put the standard html image props like `alt` and `src`.
 
-With the Image component you can render an image.
-The variant can be added with the variant prop. The default variant is `fullWidth`.
+```tsx onlyCode
+import { Image } from '@marigold/components';
+```
 
-## Properties
+## Props
 
 | Property             | Type     | Default     |
 | :------------------- | :------- | :---------- |
 | `variant` (optional) | `string` | `fullWidth` |
 
-## Import
-
-```tsx onlyCode
-import { Image } from '@marigold/components';
-```
-
 ## Usage
 
 ```tsx expandCode
diff --git a/docs/content/components/inline.mdx b/docs/content/components/inline.mdx
index cbeb3d365..be61211dc 100644
--- a/docs/content/components/inline.mdx
+++ b/docs/content/components/inline.mdx
@@ -4,35 +4,40 @@ title: Inline
 
 # Inline
 
-## Description
+Layout component to inline elements with space. This component uses the spaces from the given theme or a responsive string.
 
-Layout component to inline elements with space. This component uses the spaces from the given theme.
+<MarigoldTheme>
+  <Inline space="small">
+    <Check />
+    <Text>Check</Text>
+  </Inline>
+</MarigoldTheme>
+
+```tsx onlyCode
+import { Inline } from '@marigold/components';
+```
 
-## Properties
+## Props
 
 | Property | Type                           | Default  |
 | :------- | :----------------------------- | :------- |
 | `space`  | `ResponsiveStyleValue<string>` | `none`   |
 | `align`  | `center, top, bottom`          | `center` |
 
-## Import
-
-```tsx onlyCode
-import { Inline } from '@marigold/components';
-```
+## Examples
 
-## Live-Code Example
+More than two elements
 
 ```tsx expandCode
 <Inline space="small">
   <Check />
   <Text>Check</Text>
+  <Text>this</Text>
+  <Text>out</Text>
 </Inline>
 ```
 
-## Usage
-
-### Spacing
+Spacing
 
 ```tsx
 <Inline space="large">
@@ -51,7 +56,7 @@ import { Inline } from '@marigold/components';
 </Inline>
 ```
 
-### Nested
+Nested Inline
 
 ```tsx
 <Inline space="large">
@@ -70,7 +75,7 @@ import { Inline } from '@marigold/components';
 </Inline>
 ```
 
-### Alignment
+Different alignment
 
 ```tsx
 <Inline space="medium" align="top">
@@ -98,3 +103,9 @@ import { Inline } from '@marigold/components';
   <Text>Lorem ipsum dolor sit amet.</Text>
 </Inline>
 ```
+
+## Use cases
+
+- [ActionGroup](../action-group)
+- [Badge](../badge)
+- [Button](../button)
diff --git a/docs/content/components/label.mdx b/docs/content/components/label.mdx
index 3461cd04d..bd3a4939a 100644
--- a/docs/content/components/label.mdx
+++ b/docs/content/components/label.mdx
@@ -6,18 +6,24 @@ import { FigmaLink } from '../../src/components/FigmaLink';
 
 # Label
 
-## Description
-
 With the Label component you can add a HTML `<Label>` element to your form.
 The variant can be added with the variant prop. The default variant is `above`.
 
+<MarigoldTheme>
+  <Label htmlFor="labelId">Just a simple label</Label>
+</MarigoldTheme>
+
+```tsx onlyCode
+import { Label } from '@marigold/components';
+```
+
 <FigmaLink
   to={
     'https://www.figma.com/file/DFKyTGHAoDxOsUBPszLLxP/%F0%9F%8F%B5%EF%B8%8FMarigold?node-id=92%3A0'
   }
 />
 
-## Properties
+## Props
 
 | Property              | Type                           | Default |
 | :-------------------- | :----------------------------- | :------ |
@@ -26,112 +32,69 @@ The variant can be added with the variant prop. The default variant is `above`.
 | `color` (optional)    | `ResponsiveStyleValue<string>` | `text`  |
 | `htmlFor`             | `string`                       |         |
 
-## Import
-
-```tsx onlyCode
-import { Label } from '@marigold/components';
-```
-
-## Live-Code Example
-
-```tsx expandCode
-<Label htmlFor="labelId">Just a boring label</Label>
-```
-
-## Usage
+## Examples
 
-### Label required
+Label required
 
 ```tsx
-<Label variant="inline" htmlFor="labelId" required>
+<Label htmlFor="labelId" required>
   I am a required Label!
 </Label>
 ```
 
-### Label above
-
-```tsx
-<Label htmlFor="labelId">I am a Label!</Label>
-```
-
-### Label inline
+Label colored
 
 ```tsx
-<Label variant="inline" htmlFor="labelId">
-  I am a Label!
+<Label htmlFor="labelId" color="info">
+  I am a disabled Label!
 </Label>
 ```
 
-### Label disabled
-
-```tsx
-<Label htmlFor="labelId">I am a disabled Label!</Label>
-```
-
-### Collective Label
+## Label above
 
 ```tsx
-<Label htmlFor="labelId">
-  Collective Label
-  <Box display="flex" justifyContent="space-between" width="25%">
-    <Radio id="one" name="collective" value="RadioOne" label="Radio One" />
-    <Radio id="two" name="collective" value="RadioTwo" label="Radio Two" />
-  </Box>
-</Label>
+<>
+  <Label htmlFor="labelId">Name:</Label>
+  <Input id="labelId" />
+</>
 ```
 
-### Section Label
+## Label inline
 
 ```tsx
-<Label htmlFor="labelId" variant="section">
-  Section Label
-  <Divider variant="section" />
-</Label>
+<Inline space="xxsmall">
+  <Checkbox id="labelId" />
+  <Label variant="inline" htmlFor="labelId">
+    Agree to Marigold terms
+  </Label>
+</Inline>
 ```
 
-### Label Examples
+## Section Label
 
 ```tsx
-<Label htmlFor="labelId" variant="section">
-  Radios
-  <Divider variant="section" />
-  <Label htmlFor="labelId">
-    Radio Group
-    <Box display="flex" justifyContent="space-between" width="50%">
-      <Radio id="one" name="collective" value="RadioOne" label="Radio One" />
-      <Radio id="two" name="collective" value="RadioTwo" label="Radio Two" />
-      <Radio
-        id="three"
-        name="collective"
-        value="RadioThree"
-        label="Radio Three"
-      />
-    </Box>
+<Stack>
+  <Label htmlFor="labelId" variant="section">
+    Payment Selection
   </Label>
-</Label>
-```
-
-```tsx
-<Label htmlFor="labelId" variant="section">
-  Dropdowns
   <Divider variant="section" />
-  <Box display="flex" justifyContent="space-between" width="50%">
-    <Select
-      label="Dropdown One"
-      placeholder="Select Primary Color"
-      htmlFor="id"
-    >
-      <Item key="Red">Red</Item>
-      <Item key="Orange">Orange</Item>
-    </Select>
-    <Select
-      label="Dropdown Two"
-      placeholder="Select Secondary Color"
-      htmlFor="id2"
-    >
-      <Item key="Red">Red</Item>
-      <Item key="Orange">Orange</Item>
-    </Select>
-  </Box>
-</Label>
+  <Inline space="small">
+    <Radio id="one" name="Section1" value="RadioOne" label="Radio One" />
+    <Label variant="inline" htmlFor="labelId">
+      Visa
+    </Label>
+  </Inline>
+  <Inline space="small">
+    <Radio id="two" name="Section2" value="RadioTwo" label="Radio Two" />
+    <Label variant="inline" htmlFor="labelId">
+      Paypal
+    </Label>
+  </Inline>
+  <Inline space="small">
+    <Radio id="two" name="Section3" value="RadioThree" label="Radio Three" />
+    <Label variant="inline" htmlFor="labelId">
+      Sofortüberweisung
+    </Label>
+  </Inline>
+</Stack>
 ```
diff --git a/docs/content/components/link.mdx b/docs/content/components/link.mdx
index 37e81c77d..79727698b 100644
--- a/docs/content/components/link.mdx
+++ b/docs/content/components/link.mdx
@@ -4,11 +4,19 @@ title: Link
 
 # Link
 
-## Description
-
 Element to style links.
 
-## Properties
+<MarigoldTheme>
+  <Link href="http://www.reservix.de" target="_blank">
+    reservix.de
+  </Link>
+</MarigoldTheme>
+
+```tsx onlyCode
+import { Link } from '@marigold/components';
+```
+
+## Props
 
 | Property              | Type                 | Default |
 | :-------------------- | :------------------- | :------ |
@@ -16,30 +24,26 @@ Element to style links.
 | `variant` (optional)  | `string ⎮ string[]`  | `link`  |
 | `disabled` (optional) | boolean              |         |
 
-## Import
-
-```tsx onlyCode
-import { Link } from '@marigold/components';
-```
+## Examples
 
-## Live-Code Example
+Standard Link
 
-```tsx expandCode
+```tsx
 <Text>
-  You can jump to
-  <Link href="http://www.reservix.de" target="_blank">
-    reservix.de
+  Link something nice like
+  <Link href="#!" target="_blank">
+    Marigold
   </Link>
 </Text>
 ```
 
-## Usage
+Link disabled
 
 ```tsx
 <Text>
-  Link something nice like
-  <Link href="#!" target="_blank">
-    Marigold
+  You can jump to
+  <Link href="http://www.reservix.de" target="_blank" disabled>
+    reservix.de
   </Link>
 </Text>
 ```
diff --git a/docs/content/components/message.mdx b/docs/content/components/message.mdx
index 359bc28cc..a9ec0e302 100644
--- a/docs/content/components/message.mdx
+++ b/docs/content/components/message.mdx
@@ -6,9 +6,17 @@ import { FigmaLink } from '../../src/components/FigmaLink';
 
 # Message
 
-## Description
+Message component to display a message with a title and icon based on a `div` element and styled with a theme.
 
-Simple component to display a message with a title and icon based on a `div` element and styled with a theme.
+<MarigoldTheme>
+  <Message messageTitle="There is an update available.">
+    <Text>Hello, I am a simple info message.</Text>
+  </Message>
+</MarigoldTheme>
+
+```tsx onlyCode
+import { Message } from '@marigold/components';
+```
 
 <FigmaLink
   to={
@@ -16,28 +24,22 @@ Simple component to display a message with a title and icon based on a `div` ele
   }
 />
 
-## Properties
+## Props
 
 | Property             | Type     | Default |
 | :------------------- | :------- | :------ |
 | `messageTitle`       | `string` |         |
 | `variant` (optional) | `string` | `info`  |
 
-## Import
-
-```tsx onlyCode
-import { Message } from '@marigold/components';
-```
+## Info Message
 
-## Live-Code Example
-
-```tsx expandCode
-<Message variant="warning" messageTitle="Warning!">
-  <Text>This is a warning.</Text>
+```tsx
+<Message messageTitle="There is an update available.">
+  <Text>Hello, I am a simple info message.</Text>
 </Message>
 ```
 
-## Usage
+## Warning Message
 
 ```tsx
 <Message variant="warning" messageTitle="Danger Zone!">
@@ -45,14 +47,10 @@ import { Message } from '@marigold/components';
 </Message>
 ```
 
+## Error Message
+
 ```tsx
 <Message variant="error" messageTitle="Wrong here.">
   <Text>Hello, I am a simple error message.</Text>
 </Message>
 ```
-
-```tsx
-<Message messageTitle="There is an update available.">
-  <Text>Hello, I am a simple info message.</Text>
-</Message>
-```
diff --git a/docs/content/components/provider.mdx b/docs/content/components/provider.mdx
index f03276c75..91982d30b 100644
--- a/docs/content/components/provider.mdx
+++ b/docs/content/components/provider.mdx
@@ -4,18 +4,14 @@ title: Provider
 
 # Provider
 
-## Description
-
 `MarigoldProvider` is the container for all Marigold applications. It defines the theme and other application level settings.
 
-## Properties
+```tsx onlyCode
+import { MarigoldProvider } from '@marigold/components';
+```
+
+## Props
 
 | Property           | Type    | Default     |
 | :----------------- | :------ | :---------- |
 | `theme` (optional) | `Theme` | `undefined` |
-
-## Import
-
-```tsx onlyCode
-import { MarigoldProvider } from '@marigold/components';
-```
diff --git a/docs/content/components/text-area.mdx b/docs/content/components/text-area.mdx
new file mode 100644
index 000000000..b5a3f68f2
--- /dev/null
+++ b/docs/content/components/text-area.mdx
@@ -0,0 +1,73 @@
+---
+title: Textarea
+figma: https://www.figma.com/file/DFKyTGHAoDxOsUBPszLLxP/%F0%9F%8F%B5%EF%B8%8FMarigold?node-id=454%3A1
+---
+
+import { FigmaLink } from '../../src/components/FigmaLink';
+
+# TextArea
+
+## Description
+
+The `TextArea` component allows the user to enter multiline text with a keyboard. It consists of a label, a textarea and a help text. The later also includes error messages.
+
+<TextArea label="Enter a story" description="Anything you want to tell me!?" />
+
+```tsx onlyCode
+import { TextArea } from '@marigold/components';
+```
+
+<FigmaLink
+  to={
+    'https://www.figma.com/file/DFKyTGHAoDxOsUBPszLLxP/%F0%9F%8F%B5%EF%B8%8FMarigold?node-id=454%3A1'
+  }
+/>
+
+## Properties
+
+| Name                      | Type        | Default | Description                                                                                                                              |
+| ------------------------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| `label` (optional)        | `ReactNode` |         | The label text. If you don't want to visually display a label, provide an `aria-label` or `aria-labelledby` attribute for accessibility. |
+| `description` (optional)  | `ReactNode` |         | A helpful text                                                                                                                           |
+| `errorMessage` (optional) | `ReactNode` |         | An error message                                                                                                                         |
+| `error` (optional)        | `boolean`   | `false` | If `true`, the is considered invalid and if set the `errorMessage` is shown instead of the `description`.                                |
+| `value` (optional)        | `string`    |         | The value of the input field                                                                                                             |
+| `disabled` (optional)     | `boolean`   | `false` | If `true`, the input is disabled.                                                                                                        |
+| `required` (optional)     | `boolean`   | `false` | If `true`, the input is required.                                                                                                        |
+| `readOnly` (optional)     | `boolean`   | `false` | If `true`, the input is readOnly.                                                                                                        |
+| `onChange` (optional)     | `function`  |         | A callback function that is called with the input's current `value` when the input value changes.                                        |
+| others                    |             |         | Yes you can use all regular attributes of `textarea`!                                                                                    |
+
+## Examples
+
+### Simple TextArea
+
+```tsx
+<TextArea label="Simple" placeholder="Placeholder" />
+```
+
+### Disabled Textarea
+
+```tsx
+<TextArea
+  label="Can't touch this"
+  placeholder="Placeholder disabled"
+  disabled
+/>
+```
+
+### Required Textarea
+
+```tsx
+<TextArea label="Required Textarea" required />
+```
+
+### Error Textarea
+
+```tsx
+<TextArea
+  label="Required Textarea with error"
+  error
+  errorMessage="Oh no, we have an error!"
+/>
+```
diff --git a/docs/content/components/textarea.mdx b/docs/content/components/textarea.mdx
deleted file mode 100644
index 6a7c36109..000000000
--- a/docs/content/components/textarea.mdx
+++ /dev/null
@@ -1,85 +0,0 @@
----
-title: Textarea
----
-
-import { FigmaLink } from '../../src/components/FigmaLink';
-
-# Textarea
-
-## Description
-
-The Textarea component consists of an `<textarea>` element and a `<label>`.
-
-<FigmaLink
-  to={
-    'https://www.figma.com/file/DFKyTGHAoDxOsUBPszLLxP/%F0%9F%8F%B5%EF%B8%8FMarigold?node-id=454%3A1'
-  }
-/>
-
-## Properties
-
-| Property                  | Type      | Default     |
-| :------------------------ | :-------- | :---------- |
-| `variant` (optional)      | `string`  | `__default` |
-| `label`                   | `string`  |             |
-| `htmlFor`                 | `string`  |             |
-| `error` (optional)        | `boolean` |             |
-| `errorMessage` (optional) | `string`  |             |
-| `required` (optional)     | `boolean` |             |
-
-## Import
-
-```tsx onlyCode
-import { Textarea } from '@marigold/components';
-```
-
-## Live-Code Example
-
-```tsx expandCode
-<Textarea
-  label="Textarea One"
-  htmlFor="textareaOne"
-  placeholder="Place your text here.."
-/>
-```
-
-## Usage
-
-### Basic Textarea
-
-```tsx
-<Textarea
-  label="Textarea Two"
-  htmlFor="textareaTwo"
-  placeholder="Placeholder"
-/>
-```
-
-### Disabled Textarea
-
-```tsx
-<Textarea
-  label="Textarea Three"
-  htmlFor="textareaThree"
-  placeholder="Placeholder disabled"
-  disabled
-/>
-```
-
-### Required Textarea
-
-```tsx
-<Textarea label="Required Textarea" htmlFor="required" required />
-```
-
-### Error Textarea
-
-```tsx
-<Textarea
-  label="Required Textarea with error"
-  htmlFor="error"
-  required
-  error
-  errorMessage="Oh no, we have an error!"
-/>
-```
diff --git a/packages/components/src/TextArea/TextArea.stories.tsx b/packages/components/src/TextArea/TextArea.stories.tsx
new file mode 100644
index 000000000..cd5b5a9a3
--- /dev/null
+++ b/packages/components/src/TextArea/TextArea.stories.tsx
@@ -0,0 +1,59 @@
+import React from 'react';
+import type { Meta, ComponentStory } from '@storybook/react';
+import { TextArea } from './TextArea';
+
+export default {
+  title: 'Components/TextArea',
+  argTypes: {
+    label: {
+      control: {
+        type: 'text',
+      },
+      description: 'The label',
+      defaultValue: 'Label',
+    },
+    description: {
+      control: {
+        type: 'text',
+      },
+      description: 'Help Text',
+      defaultValue: 'This is a help text description',
+    },
+    error: {
+      control: {
+        type: 'boolean',
+      },
+      description: 'Is the input invalid?',
+      defaultValue: false,
+    },
+    errorMessage: {
+      control: {
+        type: 'text',
+      },
+      description: 'Error Message',
+      defaultValue: 'Something went wrong',
+    },
+    required: {
+      control: {
+        type: 'boolean',
+      },
+      defaultValue: false,
+    },
+    disabled: {
+      control: {
+        type: 'boolean',
+      },
+      defaultValue: false,
+    },
+    readOnly: {
+      control: {
+        type: 'boolean',
+      },
+      defaultValue: false,
+    },
+  },
+} as Meta;
+
+export const Basic: ComponentStory<typeof TextArea> = args => (
+  <TextArea {...args} />
+);
diff --git a/packages/components/src/TextArea/TextArea.tsx b/packages/components/src/TextArea/TextArea.tsx
new file mode 100644
index 000000000..cb3d546fa
--- /dev/null
+++ b/packages/components/src/TextArea/TextArea.tsx
@@ -0,0 +1,87 @@
+import React, { useRef } from 'react';
+import { useTextField } from '@react-aria/textfield';
+import { AriaTextFieldProps } from '@react-types/textfield';
+
+import { Box } from '@marigold/system';
+import { ComponentProps } from '@marigold/types';
+
+import { Field, FieldProps } from '../Field';
+
+// Theme Extension
+// ---------------
+export interface TextAreaThemeExtension<Value> {
+  textArea?: {
+    [key: string]: Value;
+  };
+}
+
+// Props
+// ---------------
+/**
+ * `react-aria` has a slightly different API for the above events.
+ * Thus, we adjust our regular props to match them.
+ */
+export type CustomTextAreEvents =
+  | 'onChange'
+  | 'onFocus'
+  | 'onBlur'
+  | 'onCopy'
+  | 'onSelect'
+  | 'onPaste'
+  | 'onCut'
+  | 'onCompositionStart'
+  | 'onCompositionUpdate'
+  | 'onCompositionEnd'
+  | 'onBeforeInput'
+  | 'onInput';
+
+export interface TextAreaProps
+  extends Omit<
+      ComponentProps<'textarea'>,
+      'value' | 'defaultValue' | CustomTextAreEvents
+    >,
+    Pick<AriaTextFieldProps, CustomTextAreEvents>,
+    Pick<FieldProps, 'label' | 'description' | 'error' | 'errorMessage'> {
+  value?: string;
+  defaultValue?: string;
+}
+
+// Component
+// ---------------
+export const TextArea = ({
+  disabled,
+  required,
+  readOnly,
+  error,
+  ...props
+}: TextAreaProps) => {
+  const { label, description, errorMessage } = props;
+  const ref = useRef<HTMLTextAreaElement>(null);
+  const { labelProps, inputProps, descriptionProps, errorMessageProps } =
+    useTextField(
+      {
+        inputElementType: 'textarea',
+        isDisabled: disabled,
+        isRequired: required,
+        isReadOnly: readOnly,
+        validationState: error ? 'invalid' : 'valid',
+        ...props,
+      },
+      ref
+    );
+
+  return (
+    <Field
+      label={label}
+      labelProps={labelProps}
+      required={required}
+      description={description}
+      descriptionProps={descriptionProps}
+      error={error}
+      errorMessage={errorMessage}
+      errorMessageProps={errorMessageProps}
+    >
+      <Box as="textarea" variant="textArea" ref={ref} {...inputProps} />
+    </Field>
+  );
+};
diff --git a/packages/components/src/TextArea/index.ts b/packages/components/src/TextArea/index.ts
new file mode 100644
index 000000000..4853311ce
--- /dev/null
+++ b/packages/components/src/TextArea/index.ts
@@ -0,0 +1,1 @@
+export * from './TextArea';
diff --git a/packages/components/src/TextField/TextField.stories.tsx b/packages/components/src/TextField/TextField.stories.tsx
index b5c84c12d..5b1c31804 100644
--- a/packages/components/src/TextField/TextField.stories.tsx
+++ b/packages/components/src/TextField/TextField.stories.tsx
@@ -71,11 +71,6 @@ export default {
         'week',
       ],
       defaultValue: 'text',
-      table: {
-        defaultValue: {
-          summary: 'text',
-        },
-      },
     },
   },
 } as Meta;
diff --git a/packages/components/src/TextField/TextField.tsx b/packages/components/src/TextField/TextField.tsx
index 227dbdd58..c459a6455 100644
--- a/packages/components/src/TextField/TextField.tsx
+++ b/packages/components/src/TextField/TextField.tsx
@@ -7,6 +7,8 @@ import { ComponentProps } from '@marigold/types';
 
 import { Field, FieldProps } from '../Field';
 
+// Props
+// ---------------
 export interface TextFieldProps
   extends Omit<
       ComponentProps<'input'>,
@@ -22,6 +24,8 @@ export interface TextFieldProps
   defaultValue?: string;
 }
 
+// Component
+// ---------------
 export const TextField = ({
   disabled,
   required,
diff --git a/packages/components/src/Textarea/Textarea.stories.tsx b/packages/components/src/Textarea/Textarea.stories.tsx
deleted file mode 100644
index 54201ac8f..000000000
--- a/packages/components/src/Textarea/Textarea.stories.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import React from 'react';
-import type { Meta, ComponentStory } from '@storybook/react';
-import { Textarea } from '.';
-
-export default {
-  title: 'Components/Textarea',
-  argTypes: {
-    variant: {
-      control: {
-        type: 'text',
-      },
-      table: {
-        defaultValue: {
-          summary: '__default',
-        },
-      },
-    },
-    label: {
-      control: {
-        type: 'text',
-      },
-      description: 'Label text',
-      defaultValue: 'Textarea Label',
-    },
-    htmlFor: {
-      control: {
-        type: 'text',
-      },
-      description: 'Bind to label',
-      defaultValue: 'textareaId',
-    },
-    error: {
-      control: {
-        type: 'boolean',
-      },
-      description: 'Error',
-      table: {
-        defaultValue: {
-          summary: false,
-        },
-      },
-    },
-    errorMessage: {
-      control: {
-        type: 'text',
-      },
-      description: 'Error Message',
-    },
-    required: {
-      control: {
-        type: 'boolean',
-      },
-      table: {
-        defaultValue: {
-          summary: false,
-        },
-      },
-    },
-  },
-} as Meta;
-
-export const Basic: ComponentStory<typeof Textarea> = args => (
-  <Textarea placeholder="Placeholder..." {...args} />
-);
diff --git a/packages/components/src/Textarea/Textarea.tsx b/packages/components/src/Textarea/Textarea.tsx
deleted file mode 100755
index cc405cbb8..000000000
--- a/packages/components/src/Textarea/Textarea.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import React, { useRef } from 'react';
-import { useTextField } from '@react-aria/textfield';
-import { AriaTextFieldProps } from '@react-types/textfield';
-
-import { Exclamation } from '@marigold/icons';
-import { ComponentProps } from '@marigold/types';
-
-import { ValidationMessage } from '../ValidationMessage';
-import { Label } from '../Label';
-import { Box } from '../Box';
-
-// Theme Extension
-// ---------------
-export interface TextareaThemeExtension<Value> {
-  textarea?: {
-    [key: string]: Value;
-  };
-}
-
-// Props
-// ---------------
-export type TextareaProps = {
-  variant?: string;
-  htmlFor: string;
-  required?: boolean;
-  error?: boolean;
-} & AriaTextFieldProps &
-  ComponentProps<'textarea'>;
-
-// Component
-// ---------------
-export const Textarea: React.FC<TextareaProps> = ({
-  variant = '',
-  htmlFor,
-  error,
-  errorMessage,
-  required,
-  children,
-  ...props
-}) => {
-  const ref = useRef<HTMLTextAreaElement>(null);
-  const { labelProps, inputProps, errorMessageProps } = useTextField(
-    {
-      ...props,
-      inputElementType: 'textarea',
-    },
-    ref
-  );
-
-  return (
-    <Box>
-      <Label htmlFor={htmlFor} required={required} {...labelProps}>
-        {props.label}
-      </Label>
-      <Box
-        as="textarea"
-        variant={`textarea.${variant}`}
-        css={{
-          outlineColor: error && 'error',
-        }}
-        {...inputProps}
-        ref={ref}
-        {...props}
-      />
-      {error && errorMessage && (
-        <ValidationMessage {...errorMessageProps}>
-          <Exclamation size={16} />
-          {errorMessage}
-        </ValidationMessage>
-      )}
-    </Box>
-  );
-};
diff --git a/packages/components/src/Textarea/index.ts b/packages/components/src/Textarea/index.ts
deleted file mode 100644
index 6449a4197..000000000
--- a/packages/components/src/Textarea/index.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export * from './Textarea';
diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts
index 4eb62ed18..a40e7ca6f 100644
--- a/packages/components/src/index.ts
+++ b/packages/components/src/index.ts
@@ -28,7 +28,7 @@ export * from './Slider';
 export * from './Switch';
 export * from './Stack';
 export * from './Text';
-export * from './Textarea';
+export * from './TextArea';
 export * from './TextField';
 export * from './Tiles';
 export * from './Tooltip';
diff --git a/packages/components/src/theme.ts b/packages/components/src/theme.ts
index 7192b12e9..266d7fba5 100644
--- a/packages/components/src/theme.ts
+++ b/packages/components/src/theme.ts
@@ -23,7 +23,7 @@ import { type SelectThemeExtension } from './Select';
 import { type SliderThemeExtension } from './Slider';
 import { type SwitchThemeExtension } from './Switch';
 import { type TextThemeExtension } from './Text';
-import { type TextareaThemeExtension } from './Textarea';
+import { type TextAreaThemeExtension } from './TextArea';
 import { type TooltipThemeExtension } from './Tooltip';
 import { type ValidationMessageThemeExtension } from './ValidationMessage';
 
@@ -47,6 +47,6 @@ export interface Theme
     SliderThemeExtension<CSSObject>,
     SwitchThemeExtension<CSSObject>,
     TextThemeExtension<CSSObject>,
-    TextareaThemeExtension<CSSObject>,
+    TextAreaThemeExtension<CSSObject>,
     TooltipThemeExtension<CSSObject>,
     ValidationMessageThemeExtension<CSSObject> {}
diff --git a/themes/theme-b2b/src/components.ts b/themes/theme-b2b/src/components.ts
index ecc1165cc..a529fb76e 100644
--- a/themes/theme-b2b/src/components.ts
+++ b/themes/theme-b2b/src/components.ts
@@ -576,7 +576,7 @@ export const components = {
       stroke: 'gray40',
     },
   },
-  textarea: {
+  textArea: {
     __default: {
       fontFamily: 'body',
       lineHeight: 'medium',
@@ -592,6 +592,7 @@ export const components = {
         outlineColor: 'blue60',
       },
       ':disabled': {
+        cursor: 'not-allowed',
         color: 'disabled',
         bg: 'gray20',
       },
diff --git a/themes/theme-core/src/components.ts b/themes/theme-core/src/components.ts
index e903dc15f..fdd8009de 100644
--- a/themes/theme-core/src/components.ts
+++ b/themes/theme-core/src/components.ts
@@ -563,7 +563,7 @@ export const components = {
       stroke: 'gray40',
     },
   },
-  textarea: {
+  textArea: {
     __default: {
       fontFamily: 'body',
       fontSize: 'xxsmall',
diff --git a/themes/theme-unicorn/src/components.ts b/themes/theme-unicorn/src/components.ts
index 3ee439db3..a042168f1 100644
--- a/themes/theme-unicorn/src/components.ts
+++ b/themes/theme-unicorn/src/components.ts
@@ -554,7 +554,7 @@ export const components = {
       stroke: 'gray40',
     },
   },
-  textarea: {
+  textArea: {
     __default: {
       fontFamily: 'body',
       lineHeight: 'medium',


Test patch:
diff --git a/packages/components/src/TextArea/TextArea.test.tsx b/packages/components/src/TextArea/TextArea.test.tsx
new file mode 100644
index 000000000..5f2215821
--- /dev/null
+++ b/packages/components/src/TextArea/TextArea.test.tsx
@@ -0,0 +1,188 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { ThemeProvider } from '@marigold/system';
+
+import { TextArea } from './TextArea';
+
+const theme = {
+  fonts: {
+    body: 'Inter Regular',
+    fancy: 'Roboto',
+  },
+  textArea: {
+    fontFamily: 'body',
+  },
+};
+
+test('renders an textarea', () => {
+  render(<TextArea label="Label" data-testid="textarea" />);
+
+  const textArea = screen.getByTestId('textarea');
+  expect(textArea).toBeInTheDocument();
+  expect(textArea instanceof HTMLTextAreaElement).toBeTruthy();
+});
+
+test('can be styled via variant', () => {
+  render(
+    <ThemeProvider theme={theme}>
+      <TextArea label="A Label" data-testid="textarea" />
+    </ThemeProvider>
+  );
+  const textArea = screen.getByTestId('textarea');
+  expect(textArea).toHaveStyle(`font-family: ${theme.fonts.body}`);
+});
+
+test('supports disabled', () => {
+  render(<TextArea label="A Label" disabled data-testid="textarea" />);
+
+  const textArea = screen.getByTestId('textarea');
+  expect(textArea).toBeDisabled();
+});
+
+test('supports required', () => {
+  render(<TextArea label="A Label" required data-testid="textarea" />);
+
+  const textArea = screen.getByTestId('textarea');
+  /** Note that the required attribute is not passed down! */
+  expect(textArea).toHaveAttribute('aria-required', 'true');
+});
+
+test('supports readonly', () => {
+  render(<TextArea label="A Label" readOnly data-testid="textarea" />);
+
+  const textArea = screen.getByTestId('textarea');
+  expect(textArea).toHaveAttribute('readonly');
+});
+
+test('supports field structure', () => {
+  render(
+    <TextArea
+      label="A Label"
+      description="Some helpful text"
+      errorMessage="Whoopsie"
+    />
+  );
+
+  const label = screen.queryByText('A Label');
+  expect(label).toBeInTheDocument();
+
+  const description = screen.queryByText('Some helpful text');
+  expect(description).toBeInTheDocument();
+
+  const error = screen.queryByText('Whoopsie');
+  expect(error).not.toBeInTheDocument();
+});
+
+test('supports field structure (with error)', () => {
+  render(
+    <TextArea
+      label="A Label"
+      description="Some helpful text"
+      error={true}
+      errorMessage="Whoopsie"
+    />
+  );
+
+  const label = screen.queryByText('A Label');
+  expect(label).toBeInTheDocument();
+
+  const description = screen.queryByText('Some helpful text');
+  expect(description).not.toBeInTheDocument();
+
+  const error = screen.queryByText('Whoopsie');
+  expect(error).toBeInTheDocument();
+});
+
+test('correctly sets up aria attributes', () => {
+  render(
+    <TextArea
+      data-testid="textarea"
+      label="A Label"
+      description="Some helpful text"
+      errorMessage="Whoopsie"
+    />
+  );
+
+  const label = screen.getByText('A Label');
+  const textarea = screen.getByTestId('textarea');
+  const description = screen.getByText('Some helpful text');
+
+  const htmlFor = label.getAttribute('for');
+  const labelId = label.getAttribute('id');
+  const inputId = textarea.getAttribute('id');
+
+  expect(label).toHaveAttribute('for', inputId);
+  expect(htmlFor).toEqual(inputId);
+  expect(textarea).toHaveAttribute('aria-labelledby', labelId);
+
+  expect(textarea).toHaveAttribute(
+    'aria-describedby',
+    description.getAttribute('id')
+  );
+
+  expect(textarea).not.toHaveAttribute('aria-invalid');
+  expect(textarea).not.toHaveAttribute('aria-errormessage');
+});
+
+test('correctly sets up aria attributes (with error)', () => {
+  render(
+    <TextArea
+      data-testid="textarea"
+      label="A Label"
+      description="Some helpful text"
+      error={true}
+      errorMessage="Whoopsie"
+    />
+  );
+
+  const label = screen.getByText('A Label');
+  const textArea = screen.getByTestId('textarea');
+  const error = screen.getByText('Whoopsie');
+
+  const htmlFor = label.getAttribute('for');
+  const labelId = label.getAttribute('id');
+  const inputId = textArea.getAttribute('id');
+
+  expect(label).toHaveAttribute('for', inputId);
+  expect(htmlFor).toEqual(inputId);
+  expect(textArea).toHaveAttribute('aria-labelledby', labelId);
+
+  expect(textArea).toHaveAttribute(
+    'aria-describedby',
+    error.getAttribute('id')
+  );
+
+  expect(textArea).toHaveAttribute('aria-invalid', 'true');
+  expect(textArea).not.toHaveAttribute('aria-errormessage');
+});
+
+test('can have default value', () => {
+  render(
+    <TextArea
+      data-testid="textarea"
+      label="A Label"
+      defaultValue="Default Value"
+    />
+  );
+
+  const textArea = screen.getByTestId('textarea');
+  expect(textArea).toHaveValue('Default Value');
+});
+
+test('can be controlled', () => {
+  const Controlled = () => {
+    const [value, setValue] = React.useState('');
+    return (
+      <>
+        <TextArea data-testid="textarea" label="A Label" onChange={setValue} />
+        <span data-testid="output">{value}</span>
+      </>
+    );
+  };
+
+  render(<Controlled />);
+
+  userEvent.type(screen.getByTestId('textarea'), 'Hello there!');
+  expect(screen.getByTestId('output')).toHaveTextContent('Hello there!');
+});
diff --git a/packages/components/src/Textarea/Textarea.test.tsx b/packages/components/src/Textarea/Textarea.test.tsx
deleted file mode 100644
index 1f488be95..000000000
--- a/packages/components/src/Textarea/Textarea.test.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { ThemeProvider } from '@marigold/system';
-import { Textarea } from '../Textarea';
-
-const theme = {
-  fonts: {
-    body: 'Inter Regular',
-    fancy: 'Roboto',
-  },
-  colors: {
-    error: 'red',
-  },
-  textarea: {
-    __default: {
-      fontFamily: 'body',
-    },
-    custom: {
-      fontFamily: 'fancy',
-    },
-  },
-};
-
-test('supports default variant', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea label="label" htmlFor="id" title="textarea" />
-    </ThemeProvider>
-  );
-  const textarea = screen.getByTitle(/textarea/);
-
-  expect(textarea).toHaveStyle(`font-family: Inter Regular`);
-});
-
-test('accepts other variant than default', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea label="label" htmlFor="id" variant="custom" title="textarea" />
-    </ThemeProvider>
-  );
-  const textarea = screen.getByTitle(/textarea/);
-
-  expect(textarea).toHaveStyle(`font-family: Roboto`);
-});
-
-test('renders correct HTML element', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea label="label" htmlFor="id" title="textarea" />
-    </ThemeProvider>
-  );
-  const textarea = screen.getByTitle(/textarea/);
-
-  expect(textarea instanceof HTMLTextAreaElement).toBeTruthy();
-});
-
-test('supports label prop', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea label="test" htmlFor="id" title="textarea" />
-    </ThemeProvider>
-  );
-  const label = screen.getByText(/test/);
-
-  expect(label instanceof HTMLLabelElement).toBeTruthy();
-});
-
-test('supports error and errorMessage prop', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea
-        error
-        errorMessage="error"
-        label="label"
-        htmlFor="id"
-        title="textarea"
-      />
-    </ThemeProvider>
-  );
-  const errorMessage = screen.getByText(/error/);
-  expect(errorMessage).toBeDefined();
-  const textarea = screen.getByTitle(/textarea/);
-  expect(textarea).toHaveStyle(`outline-color: red`);
-});
-
-test('supports required prop', () => {
-  render(
-    <ThemeProvider theme={theme}>
-      <Textarea label="test" htmlFor="id" required title="textarea" />
-    </ThemeProvider>
-  );
-  const label = screen.getByText(/test/);
-
-  // eslint-disable-next-line testing-library/no-node-access
-  expect(label.nextSibling instanceof SVGElement).toBeTruthy();
-});