Skip to content
Gx
GitHub

Textarea

A multi-line text control.

<textarea.Textarea placeholder="Tell us more." />

Installation

Run the command in the app module.

Terminal
gx add textarea

The command writes these files.

File Path in the app
Textarea.gx ui/textarea/Textarea.gx
Textarea.fixtures.go ui/textarea/Textarea.fixtures.go
styles.go ui/textarea/styles.go

Copy each file to its path in the app. Change each import of a registry package to the path of that package in the app.

ui/textarea/Textarea.gx
package textarea

props {
  // Name is the form field name.
  Name        string = ""
  // Value is the text of the textarea.
  Value       string = ""
  // Placeholder is the text that shows while the textarea is empty.
  Placeholder string = ""
  // Rows is the rows attribute. A value of zero or less renders no attribute.
  Rows        int = 0
  // Class adds classes to the root element.
  Class       string = ""
  // Attrs adds HTML attributes to the root element.
  Attrs       gx.Attrs = nil
}

<textarea name={p.Name} placeholder={p.Placeholder} data-slot="textarea" class={gx.Cx(Class, p.Class)} {...p.attrs()}>{p.Value}</textarea>
ui/textarea/Textarea.fixtures.go
package textarea

import "github.com/alternayte/gx"

var TextareaFixtures = gx.Fixtures[TextareaProps]{
	"Placeholder": {Placeholder: "Tell us more."},
	"Filled":      {Value: "A short note.", Attrs: gx.Attrs{{Key: "aria-label", Value: "Note"}}},
	"Rows":        {Rows: 6, Placeholder: "Six rows in a browser without field-sizing.", Attrs: gx.Attrs{{Key: "aria-label", Value: "Long note"}}},
	"Invalid":     {Value: "No.", Attrs: gx.Attrs{{Key: "aria-label", Value: "Reason"}, {Key: "aria-invalid", Value: "true"}}},
	"Disabled":    {Attrs: gx.Attrs{gx.Bool("disabled", true)}, Placeholder: "Disabled"},
}
ui/textarea/styles.go
package textarea

import (
	"strconv"

	"github.com/alternayte/gx"
)

// Control is the classes of a textarea without its focus ring. A group
// that draws the ring on its own border takes these classes for its
// control.
const Control = "flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40"

// Class is the classes of a textarea. A control that looks like a textarea
// takes these classes.
const Class = Control + " focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"

// attrs returns the rows attribute when the caller sets one, then the
// caller's attributes. The textarea grows with its content, so rows only
// counts in a browser without field-sizing.
func (p TextareaProps) attrs() gx.Attrs {
	if p.Rows <= 0 {
		return p.Attrs
	}
	return append(gx.Attrs{{Key: "rows", Value: strconv.Itoa(p.Rows)}}, p.Attrs...)
}

The theme must define these tokens: --input, --ring, --muted-foreground, --destructive.

Usage

<textarea.Textarea name="note" placeholder="Tell us more." />

The textarea grows with its content. It starts at two lines. Rows sets the height only in a browser without field-sizing. Set aria-invalid="true" through Attrs to show the error border.

Examples

Placeholder

<textarea.Textarea placeholder="Tell us more." />

Filled

<textarea.Textarea value="A short note." attrs={gx.Attrs{{Key: "aria-label", Value: "Note"}}} />

Rows

<textarea.Textarea rows={6} placeholder="Six rows in a browser without field-sizing." attrs={gx.Attrs{{Key: "aria-label", Value: "Long note"}}} />

Invalid

<textarea.Textarea value="No." attrs={gx.Attrs{{Key: "aria-label", Value: "Reason"}, {Key: "aria-invalid", Value: "true"}}} />

Disabled

<textarea.Textarea attrs={gx.Attrs{gx.Bool("disabled", true)}} placeholder="Disabled" />

API reference

A tag sets a prop by its name with a lower-case first letter: Class is class.

textarea.Textarea

Prop Type Default Description
Name string "" Name is the form field name.
Value string "" Value is the text of the textarea.
Placeholder string "" Placeholder is the text that shows while the textarea is empty.
Rows int 0 Rows is the rows attribute. A value of zero or less renders no attribute.
Class string "" Class adds classes to the root element.
Attrs gx.Attrs nil Attrs adds HTML attributes to the root element.

Do and do not

Do

  • Use a textarea for a message longer than one line.
  • Set a max-h- class when a long text must scroll.

Don't

  • Do not use a textarea for a single value.
  • Do not disable the resize handle unless the layout needs it.

Keyboard

Key Action
Tab Moves focus to the textarea.
Enter Inserts a new line.