QML
← All components

Textarea

Enter longer text across multiple lines, such as notes, descriptions or comments.

import Syidax.Core.Textarea

Supported QML types

TypeDefinition / role
Multi-line text field with a label, validation, character limits, counter and optional resize grip.

Learn by example

Previews are images of native Qt runs. Use the buttons below each image to view a result.

01 Basic composition

SyTextarea is the multi-line text field: the same title, helper and error lines as SyInput, around a box that wraps and scrolls the text.

Qt capture · image
Basic composition · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string label: "Bio"
        property string placeholder: "Tell us about yourself"
        property string value: ""
        property int rows: 4
        property string size: "medium"
        property string status: "default"
        property string resize: "none"
        property bool required: false
        property bool disabled: false
        property bool readonly: false
        property bool clearable: false
        property bool counter: false
        property int max: 0
        property string message: ""
    }

    

    SyTextarea {
        label: storyArgs.label
        placeholder: storyArgs.placeholder
        value: storyArgs.value
        rows: storyArgs.rows
        size: storyArgs.size
        status: storyArgs.status
        resize: storyArgs.resize
        required: storyArgs.required
        disabled: storyArgs.disabled
        readonly: storyArgs.readonly
        clearable: storyArgs.clearable
        counter: storyArgs.counter
        max: storyArgs.max
        message: storyArgs.message
        onValueChanged: if (storyArgs.value !== value) storyArgs.value = value
    }

}

02 rows

rows sets the height of the box in lines of text: the box is rows × the line height of the current size plus the padding (with a floor of 32 px).

Qt capture · image
rows · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    property QtObject settings: QtObject {
        id: storyArgs
        property int rows: 2
    }

    

    SyTextarea { rows: storyArgs.rows; value: "The content of this area is being fetched. It stays readable until the spinner masks it."; width: 360 }
}

03 size

size sets the textarea's own text scale — it does not change the box height the way it does on the input.

Qt capture · image
size · Default
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    property QtObject settings: QtObject {
        id: storyArgs
        property string size: "medium"
    }

    

    SyTextarea { label: "Bio"; placeholder: "Tell us about yourself"; size: storyArgs.size }
}

04 counter · max

counter: true shows "n/max" right-aligned under the box — the current length over the limit — and needs max to be set: with max: 0 (no limit) nothing is drawn.

Qt capture · image
counter · max · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    SyTextarea { id: featureTarget0; counter: true; max: 80; rows: 3; placeholder: "Tell us about yourself"; width: 360 }
}

05 resize

Compare the configuration and result of resize.

Qt capture · image
resize · Default
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    property QtObject settings: QtObject {
        id: storyArgs
        property string resize: "both"
    }

    

    SyTextarea { resize: storyArgs.resize; rows: 3; placeholder: "Drag the corner" }
}

06 disabled · readonly · status

The states and tones are the input's.

Qt capture · image
disabled · readonly · status · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SyTextarea { id: featureTarget0; visible: true; value: "Disabled"; disabled: true; rows: 2 }
        SyTextarea { id: featureTarget1; visible: true; value: "Read only"; readonly: true; rows: 2 }
        SyTextarea { id: featureTarget2; visible: true; value: "error"; status: "error"; rows: 2 }
    }
}

07 changed · focused · blured

The field has four signals.

Qt capture · image
changed · focused · blured · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    

    Column {
        spacing: 12
        SyTextarea {
            label: "Bio"; rows: 3; max: 40; counter: true
            onChanged: (detail) => { if (true) { output.log(("changed: %1 characters (valid: %2)").arg(detail.length).arg(detail.isValid)) } }
            onFocused: (detail) => { if (true) { output.log("focused") } }
            onBlured: (detail) => { if (true) { output.log(("blured: status %1").arg(detail.status)) } }
        }
        EventLog { id: output }
    }
}

08 setFocus · checkValidity · reportValidity · …

The same functions as the input, shown by the buttons in the demo:

Qt capture · image
setFocus · checkValidity · reportValidity · … · Default
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SyTextarea { id: bioField; label: "Bio"; rows: 2; required: true }
        Flow {
            width: 560
            spacing: 8
            SyButton { id: exampleControl1;  visible: true; text: "bioField.setFocus()"; variant: "secondary"; size: "small"; onClicked: bioField.setFocus() }
            SyButton { id: exampleControl2;  visible: true; text: "bioField.setBlur()"; variant: "secondary"; size: "small"; onClicked: bioField.setBlur() }
            SyButton { id: exampleControl3;  visible: true; text: "bioField.checkValidity()"; variant: "secondary"; size: "small"; onClicked: output.log("checkValidity() → " + bioField.checkValidity()) }
            SyButton { visible: true; text: "bioField.reportValidity()"; variant: "secondary"; size: "small"; onClicked: output.log("reportValidity() → " + bioField.reportValidity()) }
            SyButton { visible: true; text: "bioField.setCustomError()"; variant: "secondary"; size: "small"; onClicked: bioField.setCustomError() }
            SyButton { visible: true; text: "bioField.clearCustomError()"; variant: "secondary"; size: "small"; onClicked: bioField.clearCustomError() }
            SyButton { visible: true; text: "bioField.getStatus()"; variant: "secondary"; size: "small"; onClicked: output.log("getStatus() → " + JSON.stringify(bioField.getStatus())) }
        }
        EventLog { id: output }
    }
}

09 Required field and reset

Compare the untouched field, validation error and reset result.

Qt capture · image
Required field and reset · Untouched
QML code
import QtQuick
import Syidax.Core

Column {
    width: 440; spacing: 12
    SyTextarea {
        id: field; width: parent.width; name: "selection"; required: true
        label: "Required selection"; rows: 3; max: 120
        
        error: "Complete this field before continuing."
    }
    Row {
        spacing: 8
        SyButton { id: check; text: "Validate"; onClicked: field.reportValidity() }
        SyButton { id: reset; text: "Reset"; onClicked: field.reset() }
    }
    Text { text: "Status: " + (field.invalid ? "Invalid" : "Ready"); color: Theme.semantic.textDefault }
}

10 Custom error

Show an application-specific error, then reset the field.

Qt capture · image
Custom error · Untouched
QML code
import QtQuick
import Syidax.Core

Column {
    width: 440; spacing: 12
    SyTextarea {
        id: field; width: parent.width; name: "selection"; required: true
        label: "Required selection"; rows: 3; max: 120
        value: "Review the quarterly plan."
        error: "This selection is currently unavailable. Choose another."
    }
    Row {
        spacing: 8
        SyButton { id: check; text: "Show error"; onClicked: field.setCustomError() }
        SyButton { id: reset; text: "Reset"; onClicked: field.reset() }
    }
    Text { text: "Status: " + (field.invalid ? "Invalid" : "Ready"); color: Theme.semantic.textDefault }
}

API 90

Hover or select an item for its QML example and copy button.

Properties

ItemBehavior / conditions
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.
The shared field properties (name, label, required, disabled, size, message, error, touched, submitted, customError, validStatus, valid, invalid, preferredWidth, showTitle, ready) are described on the Form page; the ones below are the textarea's own or have textarea-specific meaning.

Properties

PropertyTypeDefaultDescription
string""The text. Changes with every edit and with assignments.
int4Height of the box in lines of the current text scale.
string"medium"The text scale: small 14 px (20 px line) · medium 16 px (23 px line) · large 20 px (28 px line). Changes the box height through the line height.
realrows × line + paddingThe current height of the box (at least 32). Written by the grip; writable.
string""Shown while the value is empty.
string""Title above the box
string""helper line
string""custom error copy
string""key in the owning SyForm.
string"default"default · warning · error · success — a tone independent of validation.
boolfalseEmpty value → valueMissing; adds the * mark.
boolfalseInert, always valid, not submitted; hides the × and the grip.
boolfalseSelectable, scrollable and resizable but not editable; always valid; still submitted.
boolfalseShows the × in the top-right corner while there is a value (no focus needed).
boolfalseNo border until the box is focused or invalid.
boolfalseShows "n/max" under the box; needs max > 0.
int0Minimum length of a non-empty value (tooShort); 0 = none.
int0Maximum length: typing and pasting stop there, a longer value from code is tooLong; 0 = none.
string"none"none · horizontal · vertical · both — which directions the corner grip allows.
boolfalseFocus the box as soon as the field is created.
int (read-only)—The current number of characters.
bool (read-only)—The box has active focus
bool (read-only)—the pointer is over it.
string (read-only)—value as a string.
real (read-only)—The scale values for the current size.
real (read-only)—The scale values for the current size.
real (read-only)—The scale values for the current size.
read-only—What is visible / allowed right now, and the current tone.
read-only—What is visible / allowed right now, and the current tone.
read-only—What is visible / allowed right now, and the current tone.
read-only—What is visible / allowed right now, and the current tone.
read-only—What is visible / allowed right now, and the current tone.

Methods

MethodDescription
Focus the text box (focused fires, the ring appears).
Remove the focus (blured fires, touched is set).
true when the status is ""; shows nothing.
Same verdict, and marks the field reported so the error line shows from now on.
Status "custom" and touched — the error shows at once. No arguments.
Lifts the custom status.
"" · valueMissing · tooShort · tooLong · custom.
Back to the initial value; touched, reported and custom flags cleared. The width / height set by the grip stay.

Signals

SignalArgumentsWhen
detail: { value: string, length: int, isValid: bool, status: string }value changed after load — every edit, the ×, assignments from code. Not for the initial value.
sameThe box gained active focus.
sameThe box lost focus; touched is set first.
—After the × was clicked; value is already "". Not emitted when code empties the value.

Behavior

ItemBehavior / conditions
The text. Changes with every edit and with assignments.
value changed after load — every edit, the ×, assignments from code. Not for the initial value.
Shown while the value is empty.
The current number of characters.
Height of the box in lines of the current text scale.
The text scale: small 14 px (20 px line) · medium 16 px (23 px line) · large 20 px (28 px line). Changes the box height through the line height.
The current height of the box (at least 32). Written by the grip; writable.
none · horizontal · vertical · both — which directions the corner grip allows.
resize (horizontal · vertical · both) shows a 12 px grip in the bottom-right corner; dragging it changes the field's width (minimum 80) and / or boxHeight (minimum 32). 240 px wide unless width is set (or dragged); the title, the box, the counter and the message line follow the width.
Minimum length of a non-empty value (tooShort); 0 = none.
Maximum length: typing and pasting stop there, a longer value from code is tooLong; 0 = none.
Empty value → valueMissing; adds the * mark.
The error line shows the built-in copy or error once the field is invalid (touched or reported); message is hidden meanwhile.
The error line shows the built-in copy or error once the field is invalid (touched or reported); message is hidden meanwhile. disabled > readonly > invalid > status (warning · error · success) > focus > hover > enabled.
The error line shows the built-in copy or error once the field is invalid (touched or reported); message is hidden meanwhile.
Shows "n/max" under the box; needs max > 0.
Inert, always valid, not submitted; hides the × and the grip.
Selectable, scrollable and resizable but not editable; always valid; still submitted.
default · warning · error · success — a tone independent of validation.
disabled > readonly > invalid > status (warning · error · success) > focus > hover > enabled.
disabled > readonly > invalid > status (warning · error · success) > focus > hover > enabled.
No border until the box is focused or invalid.
The box gained active focus.
The box lost focus; touched is set first.
Click or Tab focuses the box (focused); leaving it fires blured and sets touched.
Shows the × in the top-right corner while there is a value (no focus needed).
After the × was clicked; value is already "". Not emitted when code empties the value.
disabled blocks focus, typing, the × and the grip, and the field is skipped by SyForm.values().
Colors come from Theme.textarea (the warning · error · success tones are shared with the input) and follow Theme.scheme; the grip repaints on a scheme change.

Keyboard

ItemBehavior / conditions
Keyboard: Tab and Shift+Tab enter and leave the field. Hidden and disabled fields are skipped. Escape closes an open picker before continuing. Textarea uses Tab for focus navigation, including inside a modal; it does not insert indentation.