Text area

A multi-line field where users can input and edit text.

Props

name
string
Name of the input value that is received in the _change event.
value
string
Bound to value
placeholder
string
Text displayed within the input when no value is set.
rows
number
Set the number of rows.
Defaults to 3.
testId
string
Sets a data-testid attribute for automated testing.
width
string
Width of the text area.
Defaults to 100%.
maxWidth
string
Maximum width of the text area
Defaults to 60ch.
error
boolean
Sets the input to an error state
Defaults to false.
readOnly
boolean
Sets the input to a read only state.
Defaults to false.
disabled
boolean
Sets the input to a disabled state. Use [attr.disabled] with [formControl]
Defaults to false.
ariaLabel
string
Defines how the text will be translated for the screen reader. If not specified it will fall back to the name.
countby
character | word
Counting interval for characters or words, specifying whether to count every character or word.
maxCount
number
Maximum number of characters or words allowed
Defaults to -1.
autoComplete
string
Specifies the autocomplete attribute for the textarea input.
version
1 | 2
Defaults to 1.
size
default | compact
Defaults to default.
mt, mr, mb, ml
none | 3xs | 2xs | xs | s | m | l | xl | 2xl | 3xl | 4xl
Apply margin to the top, right, bottom, and/or left of the component.

Events

onChange
(event: Event) => void
_change
CustomEvent
onBlur
(event: Event) => void
_blur
CustomEvent
onKeyPress
(event: Event) => void
_keyPress
CustomEvent
Examples

Add another item in a modal

const [open, setOpen] = useState(false);
  const [type, setType] = useState<string>();
  const [name, setName] = useState<string>();
  const [description, setDescription] = useState<string>();
<GoabxButton type="tertiary" leadingIcon="add" onClick={() => setOpen(true)}>
        Add another item
      </GoabxButton>
      <GoabxModal
          heading="Add a new item"
          open={open}
          actions={
            <GoabButtonGroup alignment="end">
              <GoabxButton type="tertiary" size="compact" onClick={() => setOpen(false)}>
                Cancel
              </GoabxButton>
              <GoabxButton type="primary" size="compact" onClick={() => setOpen(false)}>
                Save new item
              </GoabxButton>
            </GoabButtonGroup>
          }
        >
          <p>Fill in the information to create a new item</p>
          <GoabxFormItem label="Type" mt="l">
            <GoabxDropdown onChange={(e) => setType(e.value)} value={type}>
              <GoabxDropdownItem value="1" label="Option 1" />
              <GoabxDropdownItem value="2" label="Option 2" />
            </GoabxDropdown>
          </GoabxFormItem>
          <GoabxFormItem label="Name" mt="l">
            <GoabxInput
              onChange={(e) => setName(e.value)}
              value={name}
              name="name"
              width="100%"
            />
          </GoabxFormItem>
          <GoabxFormItem label="Description" mt="l">
            <GoabxTextArea
              name="description"
              rows={3}
              width="100%"
              onChange={(e) => setDescription(e.value)}
              value={description}
            />
          </GoabxFormItem>
      </GoabxModal>
open = false;
  type: string | undefined = "";
  name = "";
  description = "";

  toggleModal() {
    this.open = !this.open;
  }

  updateType(event: any) {
    this.type = event.value;
  }

  updateName(event: any) {
    this.name = event.value;
  }

  updateDescription(event: any) {
    this.description = event.value;
  }
<goabx-button type="tertiary" leadingIcon="add" (onClick)="toggleModal()">Add another item</goabx-button>
<goabx-modal [open]="open" (onClose)="toggleModal()" heading="Add a new item" [actions]="actions">
  <p>Fill in the information to create a new item</p>
  <goabx-form-item label="Type" mt="l">
    <goabx-dropdown (onChange)="updateType($event)" [value]="type">
      <goabx-dropdown-item value="1" label="Option 1"></goabx-dropdown-item>
      <goabx-dropdown-item value="2" label="Option 2"></goabx-dropdown-item>
    </goabx-dropdown>
  </goabx-form-item>
  <goabx-form-item label="Name" mt="l">
    <goabx-input name="name" width="100%" (onChange)="updateName($event)" [value]="name"></goabx-input>
  </goabx-form-item>
  <goabx-form-item label="Description" mt="l">
    <goabx-textarea name="description" width="100%" [rows]="3" (onChange)="updateDescription($event)" [value]="description"></goabx-textarea>
  </goabx-form-item>
  <ng-template #actions>
    <goab-button-group alignment="end">
      <goabx-button type="tertiary" size="compact" (onClick)="toggleModal()">Cancel</goabx-button>
      <goabx-button type="primary" size="compact" (onClick)="toggleModal()">Save new item</goabx-button>
    </goab-button-group>
  </ng-template>
</goabx-modal>
const modal = document.getElementById("add-item-modal");
const openBtn = document.getElementById("open-modal-btn");
const cancelBtn = document.getElementById("cancel-btn");
const saveBtn = document.getElementById("save-btn");

openBtn.addEventListener("_click", () => {
  modal.setAttribute("open", "true");
});

modal.addEventListener("_close", () => {
  modal.removeAttribute("open");
});

cancelBtn.addEventListener("_click", () => {
  modal.removeAttribute("open");
});

saveBtn.addEventListener("_click", () => {
  modal.removeAttribute("open");
});
<goa-button version="2" id="open-modal-btn" type="tertiary" leadingicon="add">Add another item</goa-button>
<goa-modal version="2" id="add-item-modal" heading="Add a new item">
  <p>Fill in the information to create a new item</p>
  <goa-form-item version="2" label="Type" mt="l">
    <goa-dropdown version="2" id="type-dropdown">
      <goa-dropdown-item value="1" label="Option 1"></goa-dropdown-item>
      <goa-dropdown-item value="2" label="Option 2"></goa-dropdown-item>
    </goa-dropdown>
  </goa-form-item>
  <goa-form-item version="2" label="Name" mt="l">
    <goa-input version="2" name="name" width="100%" id="name-input"></goa-input>
  </goa-form-item>
  <goa-form-item version="2" label="Description" mt="l">
    <goa-textarea version="2" name="description" width="100%" rows="3" id="description-textarea"></goa-textarea>
  </goa-form-item>
  <div slot="actions">
    <goa-button-group alignment="end">
      <goa-button version="2" id="cancel-btn" type="tertiary" size="compact">Cancel</goa-button>
      <goa-button version="2" id="save-btn" type="primary" size="compact">Save new item</goa-button>
    </goa-button-group>
  </div>
</goa-modal>

Ask a long answer question with a maximum word count

const [value, setValue] = useState("");
<GoabxFormItem
      label="Provide more detail"
      helpText="Maximum 500 words. Do not include personal or financial information."
    >
      <GoabxTextArea
        name="program"
        onChange={(e) => setValue(e.value)}
        value={value}
        width="100%"
        rows={6}
        maxCount={500}
        countBy="word"
      />
    </GoabxFormItem>
form!: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      program: [""],
    });
  }
<goabx-form-item
  label="Provide more detail"
  helpText="Maximum 500 words. Do not include personal or financial information.">
  <goabx-textarea
    name="program"
    [formControl]="form.controls.program"
    width="100%"
    [rows]="6"
    [maxCount]="500"
    countBy="word">
  </goabx-textarea>
</goabx-form-item>
document.getElementById("program-textarea")?.addEventListener("_change", (e) => {
  console.log("Value:", e.detail.value);
});
<goa-form-item version="2"
  label="Provide more detail"
  helptext="Maximum 500 words. Do not include personal or financial information.">
  <goa-textarea version="2"
    name="program"
    id="program-textarea"
    width="100%"
    rows="6"
    maxcount="500"
    countby="word">
  </goa-textarea>
</goa-form-item>

Give context before asking a long answer question

const [textValue, setTextValue] = useState("");

  const handleChange = (event: GoabTextAreaOnChangeDetail) => {
    setTextValue(event.value);
  };

  const handleContinue = () => {
    console.log("Submitted:", textValue);
  };
<GoabxLink leadingIcon="arrow-back" size="small" mb="none">
        Back
      </GoabxLink>

      <GoabText as="h2" mt="xl" mb="m">Submit a question about your benefits</GoabText>
      <GoabText mt="none" mb="xl">
        If you need clarification about your benefit eligibility, payment schedule, or application status, submit your
        question here.
      </GoabText>

      <form>
        <GoabxFormItem
          label="Provide details about your situation"
          helpText="Include specific details to help us answer your question quickly.">
          <GoabxTextArea
            name="program"
            onChange={handleChange}
            value={textValue}
            maxCount={400}
            countBy="character"
          />
        </GoabxFormItem>
      </form>

      <GoabDetails mt="m" heading="What kind of information is useful?">
        <p>
          Include your benefit program name, mention any recent correspondence you received and/or provide any
          relevant case or reference numbers.
        </p>
      </GoabDetails>

      <GoabButtonGroup alignment="start" mt="2xl">
        <GoabxButton type="primary" onClick={handleContinue}>
          Continue
        </GoabxButton>
      </GoabButtonGroup>
form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      program: [""]
    });
  }

  onContinue(): void {
    console.log("Submitted:", this.form.get("program")?.value);
  }
<goabx-link leadingIcon="arrow-back" size="small" mb="none">
  Back
</goabx-link>

<goab-text as="h2" mt="xl" mb="m">Submit a question about your benefits</goab-text>
<goab-text mt="none" mb="xl">
  If you need clarification about your benefit eligibility, payment schedule, or application status, submit your
  question here.
</goab-text>

<form [formGroup]="form">
  <goabx-form-item
    label="Provide details about your situation"
    helpText="Include specific details to help us answer your question quickly.">
    <goabx-textarea
      formControlName="program"
      name="program"
      [maxCount]="400"
      countBy="character">
    </goabx-textarea>
  </goabx-form-item>
</form>

<goab-details mt="m" heading="What kind of information is useful?">
  <p>
    Include your benefit program name, mention any recent correspondence you received and/or provide any
    relevant case or reference numbers.
  </p>
</goab-details>

<goab-button-group alignment="start" mt="2xl">
  <goabx-button type="primary" (onClick)="onContinue()">
    Continue
  </goabx-button>
</goab-button-group>
const textarea = document.getElementById('program-textarea');
const continueBtn = document.getElementById('continue-btn');

continueBtn.addEventListener('_click', () => {
  console.log('Submitted:', textarea.value);
});
<goa-link leadingicon="arrow-back" size="small" mb="none">
  Back
</goa-link>

<goa-text as="h2" mt="xl" mb="m">Submit a question about your benefits</goa-text>
<goa-text mt="none" mb="xl">
  If you need clarification about your benefit eligibility, payment schedule, or application status, submit your
  question here.
</goa-text>

<form>
  <goa-form-item version="2"
    label="Provide details about your situation"
    helptext="Include specific details to help us answer your question quickly.">
    <goa-textarea version="2"
      id="program-textarea"
      name="program"
      maxcount="400"
      countby="character">
    </goa-textarea>
  </goa-form-item>
</form>

<goa-details mt="m" heading="What kind of information is useful?">
  <p>
    Include your benefit program name, mention any recent correspondence you received and/or provide any
    relevant case or reference numbers.
  </p>
</goa-details>

<goa-button-group alignment="start" mt="2xl">
  <goa-button version="2" id="continue-btn" type="primary">
    Continue
  </goa-button>
</goa-button-group>

Review and action

<GoabGrid minChildWidth="315px">
      <GoabContainer accent="thin" type="non-interactive">
        <GoabText size="heading-m" mt="none" mb="m">Appearance details</GoabText>
        <GoabGrid minChildWidth="200px" gap="m">
          <GoabBlock direction="column" gap="xs">
            <GoabText size="body-s" color="secondary" mt="none" mb="none">Accused name</GoabText>
            <GoabText size="body-m" mt="none" mb="none">Doe, John Scott</GoabText>
          </GoabBlock>

          <GoabBlock direction="column" gap="xs">
            <GoabText size="body-s" color="secondary" mt="none" mb="none">Date of birth</GoabText>
            <GoabText size="body-m" mt="none" mb="none">Mar 14, 2021</GoabText>
          </GoabBlock>

          <GoabBlock direction="column" gap="xs">
            <GoabText size="body-s" color="secondary" mt="none" mb="none">Court location</GoabText>
            <GoabText size="body-m" mt="none" mb="none">Calgary</GoabText>
          </GoabBlock>

          <GoabBlock direction="column" gap="xs">
            <GoabText size="body-s" color="secondary" mt="none" mb="none">Upcoming appearance date(s)</GoabText>
            <GoabText size="body-m" mt="none" mb="none">Sep 20, 2021</GoabText>
          </GoabBlock>
        </GoabGrid>

        <GoabText size="heading-xs" mt="l" mb="s">Docket number(s) &amp; charges</GoabText>
        <GoabContainer type="non-interactive" padding="compact">
          <GoabText size="heading-xs" mt="none" mb="xs">1
    h3.review-h3 {
      margin-bottom: var(--goa-space-m);
    }
    label.review-label {
      font: var(--goa-typography-body-s);
      color: var(--goa-color-text-secondary);
    }
    .review-content {
      font: var(--goa-typography-body-m);
    }
    p.review-content {
      margin-bottom: 0;
    }
    h5.review-h5 {
      font: var(--goa-typography-body-m);
      color: var(--goa-color-text-secondary);
      margin-top: var(--goa-space-m);
      margin-bottom: var(--goa-space-m);
    }
    h6.review-h6 {
      font: var(--goa-typography-heading-s);
      margin-top: 0;
      margin-bottom: 0;
    }
  `,
  ],
})
export class ReviewAndActionComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      case: ["
form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      case: [""],
      reason: [""],
      message: [""],
    });
  }

  onClick(): void {
    console.log("Confirm clicked!");
  }
<goab-grid minChildWidth="315px">
  <goab-container accent="thin" type="non-interactive">
    <goab-text size="heading-m" mt="none" mb="m">Appearance details</goab-text>
    <goab-grid minChildWidth="200px" gap="m">
      <goab-block direction="column" gap="xs">
        <goab-text size="body-s" color="secondary" mt="none" mb="none">Accused name</goab-text>
        <goab-text size="body-m" mt="none" mb="none">Doe, John Scott</goab-text>
      </goab-block>

      <goab-block direction="column" gap="xs">
        <goab-text size="body-s" color="secondary" mt="none" mb="none">Date of birth</goab-text>
        <goab-text size="body-m" mt="none" mb="none">Mar 14, 2021</goab-text>
      </goab-block>

      <goab-block direction="column" gap="xs">
        <goab-text size="body-s" color="secondary" mt="none" mb="none">Court location</goab-text>
        <goab-text size="body-m" mt="none" mb="none">Calgary</goab-text>
      </goab-block>

      <goab-block direction="column" gap="xs">
        <goab-text size="body-s" color="secondary" mt="none" mb="none">Upcoming appearance date(s)</goab-text>
        <goab-text size="body-m" mt="none" mb="none">Sep 20, 2021</goab-text>
      </goab-block>
    </goab-grid>

    <goab-text size="heading-xs" mt="l" mb="s">Docket number(s) &amp; charges</goab-text>
    <goab-container type="non-interactive" padding="compact">
      <goab-text size="heading-xs" mt="none" mb="xs">1) 12345678</goab-text>
      <goab-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goab-text>
      <goab-text size="body-m" mt="none" mb="none">CC 268(1) - Aggravated assault</goab-text>
    </goab-container>

    <goab-container type="non-interactive" padding="compact">
      <goab-text size="heading-xs" mt="none" mb="xs">2) 12345678</goab-text>
      <goab-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goab-text>
      <goab-text size="body-m" mt="none" mb="none">CC 268(1) - Aggravated assault</goab-text>
    </goab-container>
  </goab-container>

  <goab-container accent="thin" width="content">
    <form [formGroup]="form">
      <goab-text size="heading-m" mt="none" mb="m">Adjournment request</goab-text>
      <goab-text size="body-m" mt="none" mb="none">
        Keep track of the individuals who are placed in lodges and may qualify for the Lodge
        Assistance Program subsidy.
      </goab-text>

      <goabx-form-item label="Case history and new request" mt="l">
        <goabx-radio-group name="case" orientation="horizontal" formControlName="case">
          <goabx-radio-item value="grant" label="Grant"></goabx-radio-item>
          <goabx-radio-item value="deny" label="Deny"></goabx-radio-item>
        </goabx-radio-group>
      </goabx-form-item>

      <goabx-form-item label="Reason to deny" mt="l">
        <goabx-dropdown name="reason" width="100%" formControlName="reason">
          <goabx-dropdown-item value="1" label="Incomplete Application"></goabx-dropdown-item>
          <goabx-dropdown-item value="2" label="Eligibility Criteria Not Met"></goabx-dropdown-item>
          <goabx-dropdown-item value="3" label="Documentation Verification Failure"></goabx-dropdown-item>
        </goabx-dropdown>
      </goabx-form-item>

      <goabx-form-item label="Message" mt="l">
        <goabx-textarea name="message" [rows]="5" width="100%" formControlName="message"></goabx-textarea>
      </goabx-form-item>

      <goabx-button mt="xl" (onClick)="onClick()">Confirm adjournment</goabx-button>
    </form>
  </goab-container>
</goab-grid>
document.getElementById("confirm-btn").addEventListener("_click", () => {
  console.log("Confirm clicked!");
});
<goa-grid minchildwidth="315px">
  <goa-container accent="thin" type="non-interactive">
    <goa-text size="heading-m" mt="none" mb="m">Appearance details</goa-text>
    <goa-grid minchildwidth="200px" gap="m">
      <goa-block direction="column" gap="xs">
        <goa-text size="body-s" color="secondary" mt="none" mb="none">Accused name</goa-text>
        <goa-text size="body-m" mt="none" mb="none">Doe, John Scott</goa-text>
      </goa-block>

      <goa-block direction="column" gap="xs">
        <goa-text size="body-s" color="secondary" mt="none" mb="none">Date of birth</goa-text>
        <goa-text size="body-m" mt="none" mb="none">Mar 14, 2021</goa-text>
      </goa-block>

      <goa-block direction="column" gap="xs">
        <goa-text size="body-s" color="secondary" mt="none" mb="none">Court location</goa-text>
        <goa-text size="body-m" mt="none" mb="none">Calgary</goa-text>
      </goa-block>

      <goa-block direction="column" gap="xs">
        <goa-text size="body-s" color="secondary" mt="none" mb="none">Upcoming appearance date(s)</goa-text>
        <goa-text size="body-m" mt="none" mb="none">Sep 20, 2021</goa-text>
      </goa-block>
    </goa-grid>

    <goa-text size="heading-xs" mt="l" mb="s">Docket number(s) &amp; charges</goa-text>
    <goa-container type="non-interactive" padding="compact">
      <goa-text size="heading-xs" mt="none" mb="xs">1) 12345678</goa-text>
      <goa-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goa-text>
      <goa-text size="body-m" mt="none" mb="none">CC 268(1) - Aggravated assault</goa-text>
    </goa-container>

    <goa-container type="non-interactive" padding="compact">
      <goa-text size="heading-xs" mt="none" mb="xs">2) 12345678</goa-text>
      <goa-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goa-text>
      <goa-text size="body-m" mt="none" mb="none">CC 268(1) - Aggravated assault</goa-text>
    </goa-container>
  </goa-container>

  <goa-container accent="thin" width="content">
    <form>
      <goa-text size="heading-m" mt="none" mb="m">Adjournment request</goa-text>
      <goa-text size="body-m" mt="none" mb="none">
        Keep track of the individuals who are placed in lodges and may qualify for the Lodge
        Assistance Program subsidy.
      </goa-text>

      <goa-form-item version="2" label="Case history and new request" mt="l">
        <goa-radio-group version="2" name="case" orientation="horizontal">
          <goa-radio-item value="grant" label="Grant"></goa-radio-item>
          <goa-radio-item value="deny" label="Deny"></goa-radio-item>
        </goa-radio-group>
      </goa-form-item>

      <goa-form-item version="2" label="Reason to deny" mt="l">
        <goa-dropdown version="2" name="reason" width="100%">
          <goa-dropdown-item value="1" label="Incomplete Application"></goa-dropdown-item>
          <goa-dropdown-item value="2" label="Eligibility Criteria Not Met"></goa-dropdown-item>
          <goa-dropdown-item value="3" label="Documentation Verification Failure"></goa-dropdown-item>
        </goa-dropdown>
      </goa-form-item>

      <goa-form-item version="2" label="Message" mt="l">
        <goa-textarea version="2" name="message" rows="5" width="100%"></goa-textarea>
      </goa-form-item>

      <goa-button version="2" id="confirm-btn" mt="xl">Confirm adjournment</goa-button>
    </form>
  </goa-container>
</goa-grid>

States

Submit

When you must disable a button or input:

  • Provide nearby text explaining what needs to happen first
  • Consider showing the element enabled with validation on submit instead
  • Use aria-describedby to link the disabled element to explanatory text
Don't disable buttons or inputs without explaining why. Disabled controls can be confusing and users may not understand why they can't interact with an element.

Other

The form item automatically associates the label with the input for screen readers, ensuring your form is accessible.

Use a form item wrapper on all inputs to add a label, helper text, error message, and more.

Sizing

Known input length: Use fixed-width inputs for content with a specific length, such as postal code (7 characters) or year (4 characters).

Unknown input length: If you don’t know how many characters the user will need (like their name), make your text input 100% of the container.

Size text inputs based on the expected content length to help users understand what information is needed.

Types

Use a text area to input content longer than a single line, such as descriptions, comments, or feedback.
All GoA Design System components are built to meet WCAG 2.2 AA standards. The following guidelines provide additional context for accessible implementation.

No accessibility-specific guidelines have been documented for this component yet.