Back to Reflex

Text Area

docs/library/forms/text_area.md

0.9.8a14.6 KB
Original Source
python
import reflex as rx

Text Area

A text area is a multi-line text input field.

Basic Example

The text area component can be controlled by a single value. The on_blur prop can be used to update the value when the text area loses focus.

python
class TextAreaBlur(rx.State):
    text: str = "Hello World!"

    @rx.event
    def set_text(self, text: str):
        self.text = text


def blur_example():
    return rx.vstack(
        rx.heading(TextAreaBlur.text, as_="h2"),
        rx.text_area(
            placeholder="Type here...",
            on_blur=TextAreaBlur.set_text,
        ),
    )

Text Area in forms

Here we show how to use a text area in a form. We use the name prop to identify the text area in the form data. The form data is then passed to the submit_feedback method to be processed.

python
class TextAreaFeedbackState(rx.State):
    feedback: str = ""
    submitted: bool = False

    @rx.event
    def set_feedback(self, value: str):
        self.feedback = value

    @rx.event
    def submit_feedback(self, form_data: dict):
        self.submitted = True

    @rx.event
    def reset_form(self):
        self.feedback = ""
        self.submitted = False


def feedback_form():
    return rx.cond(
        TextAreaFeedbackState.submitted,
        rx.card(
            rx.vstack(
                rx.text("Thank you for your feedback!"),
                rx.button(
                    "Submit another response", on_click=TextAreaFeedbackState.reset_form
                ),
            ),
        ),
        rx.card(
            rx.form(
                rx.flex(
                    rx.text("Are you enjoying Reflex?"),
                    rx.text_area(
                        placeholder="Write your feedback…",
                        value=TextAreaFeedbackState.feedback,
                        on_change=TextAreaFeedbackState.set_feedback,
                        resize="vertical",
                    ),
                    rx.button("Send", type="submit"),
                    direction="column",
                    spacing="3",
                ),
                on_submit=TextAreaFeedbackState.submit_feedback,
            ),
        ),
    )

Submitting on Enter

By default, pressing Enter in a text area inserts a new line. Set the enter_key_submit prop to submit the enclosing form when Enter is pressed instead. Shift+Enter still inserts a new line, so multi-line input remains possible.

python
class EnterSubmitState(rx.State):
    submitted_text: str = ""

    @rx.event
    def handle_submit(self, form_data: dict):
        self.submitted_text = form_data["message"]


def enter_key_submit_example():
    return rx.vstack(
        rx.cond(
            EnterSubmitState.submitted_text != "",
            rx.text("Submitted: ", EnterSubmitState.submitted_text),
            rx.text("Nothing submitted yet."),
        ),
        rx.form(
            rx.text_area(
                name="message",
                placeholder="Type and press Enter to submit",
                enter_key_submit=True,
            ),
            on_submit=EnterSubmitState.handle_submit,
        ),
        width="100%",
    )

enter_key_submit accepts a Var, so it can be toggled dynamically — for example, disabling Enter-to-submit while a previous submission is still being processed: enter_key_submit=~State.is_loading.

md
# `enter_key_submit` cannot be combined with `on_key_down`.

The `enter_key_submit` prop is implemented with its own key down handler, so
passing both to the same component raises an error. Note that a Python
`on_key_down` handler receives only the key and modifier flags, not the raw
event, so it cannot call `preventDefault()` to stop Enter from inserting a
newline. Replicating Enter-to-submit alongside custom key handling therefore
needs a client-side handler (e.g. via `rx.call_script`), not a plain
`on_key_down` event handler.

Auto-Expanding Height

Set auto_height=True to make a text area grow to fit its content as the user types, instead of scrolling inside a fixed box. Pair it with rows="1" and min_height="0" so it starts at a single line and expands from there.

python
def auto_height_example():
    return rx.text_area(
        placeholder="Type a few lines — the box grows to fit",
        auto_height=True,
        rows="1",
        min_height="0",
        width="100%",
    )

auto_height attaches a client-side handler that resizes the element on every input, so its height always matches the content. Add a CSS min_height / max_height when you want to cap how small or tall it can get.