# Textarea Behavior

**MUST** · **ID:** `forms-textarea-behavior` · **Category:** forms
**Source:** [Vercel](https://github.com/vercel-labs/agent-skills/blob/main/skills/web-design-guidelines/SKILL.md)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/forms-textarea-behavior

> MUST: In `<textarea>`, ⌘/Ctrl+Enter submits; Enter adds newline

In textarea, Enter should insert a new line while Cmd/Ctrl+Enter submits

Textareas are for multi-line input, so Enter must create new lines. Users who want to submit can use the keyboard modifier (Cmd on Mac, Ctrl on Windows/Linux) plus Enter. This prevents accidental submission when writing paragraphs.

## Bad — do not do this

`forms-textarea-behavior-bad`

```tsx
import { useState } from 'react';

export function TextareaBehaviorBad() {
  const [message, setMessage] = useState('');
  const [submitted, setSubmitted] = useState(false);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitted(true);
    setTimeout(() => setSubmitted(false), 2000);
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit(e);
    }
  };

  return (
    <div className="w-full max-w-sm">
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label htmlFor="bad-message" className="block text-sm font-medium text-foreground mb-1">
            Your Message
          </label>
          <textarea
            id="bad-message"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            onKeyDown={handleKeyDown}
            rows={4}
            className="w-full px-3 py-2 border border-border rounded-lg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring resize-none"
            placeholder="Write your message..."
          />
        </div>
        <button
          type="submit"
          className="w-full px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
        >
          {submitted ? 'Sent!' : 'Send Message'}
        </button>
      </form>
      <p className="text-xs text-muted-foreground mt-4">
        Enter submits (can't add new lines easily)
      </p>
    </div>
  );
}
```

## Good — do this

`forms-textarea-behavior-good`

```tsx
import { useState } from 'react';

export function TextareaBehaviorGood() {
  const [message, setMessage] = useState('');
  const [submitted, setSubmitted] = useState(false);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitted(true);
    setTimeout(() => setSubmitted(false), 2000);
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      handleSubmit(e);
    }
  };

  return (
    <div className="w-full max-w-sm">
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label htmlFor="good-message" className="block text-sm font-medium text-foreground mb-1">
            Your Message
          </label>
          <textarea
            id="good-message"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            onKeyDown={handleKeyDown}
            rows={4}
            className="w-full px-3 py-2 border border-border rounded-lg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring resize-none"
            placeholder="Write your message..."
          />
        </div>
        <button
          type="submit"
          className="w-full px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
        >
          {submitted ? 'Sent!' : 'Send Message'}
        </button>
      </form>
      <p className="text-xs text-success mt-4">
        Enter adds new lines, Cmd/Ctrl+Enter submits
      </p>
    </div>
  );
}
```

## References

- [HTML textarea element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/textarea)
