Text Area
1.11.0The text area component provides users with a resizable input field for entering longer text content. It includes features like character counting, validation states, and optional helper text to guide users through data entry tasks.
import {TextAreaModule} from "@qualcomm-ui/angular/text-area"Examples
Simple
The simple <q-text-area> bundles all subcomponents together into a single component.
<q-text-area
class="w-72"
hint="Optional hint"
label="Label"
placeholder="Placeholder text"
/>
Composite
Build with the composite API for granular control. This API requires you to provide each subcomponent, but gives you full control over the structure and layout.
<div class="w-72" q-text-area-root>
<label q-text-area-label>Label</label>
<div q-text-area-counter></div>
<textarea placeholder="Placeholder text" q-text-area-input></textarea>
<div q-text-area-hint>Optional hint</div>
<div q-text-area-error-text>Optional error text</div>
</div>
Counter
Display a character count using counter or by setting a maxLength.
By default, the counter displays:
count/maxwhenmaxLengthis setcountwhen onlycounteris used
Use the q-text-area-counter directive with a display function to customize the format.
<q-text-area class="w-72" counter label="Counter without maxLength" />
<q-text-area
class="w-72"
label="Counter with maxLength"
[maxLength]="10"
/>
<q-text-area class="w-72" label="Custom counter display" [maxLength]="10">
<div q-text-area-counter [display]="customDisplay"></div>
</q-text-area>
Sizes
Customize size using size. The default size is md.
<q-text-area class="w-56" defaultValue="sm" size="sm" />
<q-text-area class="w-60" defaultValue="md" />
<q-text-area class="w-64" defaultValue="lg" size="lg" />
Value Changed
Listen to changes with the valueChanged output.
import {Component} from "@angular/core"
import {TextAreaModule} from "@qualcomm-ui/angular/text-area"
@Component({
imports: [TextAreaModule],
selector: "text-area-value-changed-demo",
template: `
<q-text-area
class="w-72"
defaultValue="Initial value"
label="Label"
placeholder="Placeholder text"
(valueChanged)="onValueChanged($event)"
/>
`,
})
export class TextAreaValueChangedDemo {
onValueChanged(newValue: string) {
console.log("Value changed:", newValue)
}
}Error Text and Indicator
Error messages are displayed using two inputs:
The error text and indicator will only render when invalid is true.
<q-text-area
#textArea
class="w-72"
errorText="You must enter at least 10 characters."
label="Label"
placeholder="Enter at least 10 characters"
required
[invalid]="value().length < 10"
[(ngModel)]="value"
/>
Forms
Control and validate the input value using Angular form control bindings.
Template Forms
When using template-driven forms with ngModel, perform validation manually in your component and pass the result to invalid.
import {Component, signal} from "@angular/core"
import {FormsModule} from "@angular/forms"
import {TextAreaModule} from "@qualcomm-ui/angular/text-area"
@Component({
imports: [TextAreaModule, FormsModule],
selector: "text-area-template-forms-demo",
template: `
<q-text-area
#textArea
class="w-72"
errorText="You must enter at least 10 characters."
hint="10 characters minimum"
label="Feedback"
placeholder="Enter your feedback"
required
[invalid]="value().length < 10"
[(ngModel)]="value"
/>
`,
})
export class TextAreaTemplateFormsDemo {
readonly value = signal<string>("Make me shorter")
}States
When using template forms, disabled, readOnly, and invalid govern the interactive state of the control.
<q-text-area disabled label="Disabled" placeholder="Disabled" />
<q-text-area label="Read only" placeholder="Read only" readOnly />
<q-text-area
errorText="Invalid"
invalid
label="Invalid"
placeholder="Invalid"
/>
Required
When using template forms, pass required to apply the RequiredValidator to the form control.
<q-text-area
class="w-72"
label="Required"
placeholder="Enter text"
required
[(ngModel)]="value"
/>
Reactive Forms
Use Reactive Forms for better control of form state and validation.
import {Component, inject, signal} from "@angular/core"
import {FormBuilder, ReactiveFormsModule, Validators} from "@angular/forms"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {TextAreaModule} from "@qualcomm-ui/angular/text-area"
@Component({
imports: [TextAreaModule, ButtonModule, ReactiveFormsModule],
selector: "text-area-reactive-forms-demo",
template: `
<form
class="mx-auto flex w-72 flex-col gap-3"
[formGroup]="feedbackForm"
(ngSubmit)="onSubmit()"
>
<q-text-area
class="w-full"
errorText="Feedback must be at least 10 characters long"
formControlName="feedback"
hint="Minimum 10 characters"
label="Feedback"
placeholder="Tell us about your experience"
[invalid]="isFieldInvalid('feedback')"
/>
<div class="flex w-full justify-end">
<button
emphasis="primary"
q-button
type="submit"
variant="fill"
[disabled]="isSubmitting()"
>
Submit Feedback
</button>
</div>
</form>
`,
})
export class TextAreaReactiveFormsDemo {
private fb = inject(FormBuilder)
readonly isSubmitting = signal(false)
feedbackForm = this.fb.group({
feedback: ["", [Validators.required, Validators.minLength(10)]],
})
isFieldInvalid(fieldName: string): boolean {
const field = this.feedbackForm.get(fieldName)
return !!(field && field.invalid && (field.dirty || field.touched))
}
onSubmit() {
if (this.feedbackForm.valid) {
this.isSubmitting.set(true)
console.log("Form submitted:", this.feedbackForm.value)
// Simulate API call
setTimeout(() => {
this.isSubmitting.set(false)
}, 1000)
} else {
// Mark all fields as touched to show validation errors
this.feedbackForm.markAllAsTouched()
}
}
}State Guidelines
The disabled, invalid, and required inputs have no effect when using Reactive Forms. Use the equivalent Reactive Form bindings instead:
disabledField = new FormControl("")
invalidField = new FormControl("Too short", {
validators: [Validators.required, Validators.minLength(10)],
})
requiredField = new FormControl("", {validators: [Validators.required]})
ngOnInit() {
this.disabledField.disable()
this.invalidField.markAsDirty()
}
Composite API & Forms
When using the composite API with Angular Forms, always apply form control bindings to the q-text-area-root directive.
<div
class="w-72"
q-text-area-root
[invalid]="isInvalid()"
[(ngModel)]="value"
>
<label q-text-area-label>Composite Forms</label>
<div q-text-area-counter></div>
<textarea placeholder="Enter text" q-text-area-input></textarea>
<div q-text-area-error-text>Must be at least 30 characters long</div>
</div>
Explorer
API
<q-text-area>
The <q-text-area> component extends the q-text-area-root directive with the following properties:
boolean-
true: always show the counter-
false: never show the counter-
undefined (default): only show the counter if maxLength is setstring<div q-text-area-error-text>...</div>
string<div q-text-area-hint>...</div>
string<label q-text-area-label>...</label>
stringComposite API
q-text-area-root
string'ltr' | 'rtl'
boolean() =>
| Node
| ShadowRoot
| Document
booleannumberstringbooleanboolean| 'sm'
| 'md'
| 'lg'
stringclass'qui-text-area__root'data-disableddata-focusdata-invaliddata-size| 'sm'
| 'md'
| 'lg'
data-text-area-part'root'q-text-area-label
class'qui-text-area__label'data-disableddata-focusdata-invaliddata-size| 'sm'
| 'md'
| 'lg'
data-text-area-part'label'q-text-area-hint
class'qui-text-area__hint'data-disableddata-text-area-part'hint'hiddenbooleanq-text-area-counter
<div>
element by default.class'qui-text-area__counter'data-disableddata-focusdata-invaliddata-maxnumberdata-size| 'sm'
| 'md'
| 'lg'
data-text-area-part'counter'q-text-area-input
ngModel
or formControl to this element. Apply them to the root element instead.stringclass'qui-text-area__input'data-disableddata-emptydata-focusdata-invaliddata-readonlydata-size| 'sm'
| 'md'
| 'lg'
data-text-area-part'input'q-text-area-error-text
class'qui-text-area__error-text'data-text-area-part'error-text'hiddenboolean