TextField

The TextField component provides single-line text input with optional length limiting. It's designed for typical form inputs and automatically removes newlines to keep content on one line.

using Fugl

function MyApp()
    # Store EditorState for different fields
    name_state = Ref(EditorState("John Doe"))
    email_state = Ref(EditorState("user@example.com"))
    phone_state = Ref(EditorState("555-1234"))

    # Dark theme styles
    dark_container_style = ContainerStyle(
        background_color = Vec4f(0.12, 0.12, 0.12, 1.0),
        border_color = Vec4f(0.3, 0.3, 0.3, 1.0),
        border_width = 1.0f0,
        corner_radius = 8.0f0
    )

    dark_text_style = TextStyle(
        color = Vec4f(0.9, 0.9, 0.9, 1.0),
        size_points = 16
    )

    dark_card_style = ContainerStyle(
        background_color = Vec4f(0.18, 0.18, 0.18, 1.0),
        border_color = Vec4f(0.4, 0.4, 0.4, 1.0),
        border_width = 1.0f0,
        corner_radius = 8.0f0
    )

    dark_card_title_style = TextStyle(
        color = Vec4f(0.9, 0.9, 0.9, 1.0),
        size_points = 16
    )

    dark_field_style = TextBoxStyle(
        text_style = TextStyle(color = Vec4f(0.9, 0.9, 0.9, 1.0), size_points = 14),
        background_color_focused = Vec4f(0.2, 0.2, 0.25, 1.0),
        background_color_unfocused = Vec4f(0.15, 0.15, 0.15, 1.0),
        border_color = Vec4f(0.4, 0.6, 0.8, 1.0),
        border_width = 1.5f0,
        corner_radius = 6.0f0
    )

    Container(
        IntrinsicColumn([
            Card(
                "Full Name",
                TextField(
                    name_state[];
                    style=dark_field_style,
                    on_state_change=(new_state) -> name_state[] = new_state,
                    on_change=(new_text) -> println("Name changed to: '", new_text, "'")
                ),
                style=dark_card_style,
                title_style=dark_card_title_style
            ),
            Card(
                "Email (max 30 chars)",
                TextField(
                    email_state[];
                    max_length=30,
                    style=dark_field_style,
                    on_state_change=(new_state) -> email_state[] = new_state,
                    on_change=(new_text) -> println("Email changed to: '", new_text, "' (length: ", length(new_text), ")")
                ),
                style=dark_card_style,
                title_style=dark_card_title_style
            ),
            Card(
                "Phone (max 15 chars)",
                TextField(
                    phone_state[];
                    max_length=15,
                    style=dark_field_style,
                    on_state_change=(new_state) -> phone_state[] = new_state,
                    on_change=(new_text) -> println("Phone changed to: '", new_text, "' (length: ", length(new_text), ")")
                ),
                style=dark_card_style,
                title_style=dark_card_title_style
            ),
            Container(
                IntrinsicColumn([
                    IntrinsicHeight(Fugl.Text("Current Values:", style=TextStyle(size_points=16, color=Vec4f(0.8, 0.8, 0.8, 1.0)))),
                    IntrinsicHeight(Fugl.Text("Name: \"$(name_state[].text)\"", style=TextStyle(size_points=14, color=Vec4f(0.7, 0.7, 0.7, 1.0)))),
                    IntrinsicHeight(Fugl.Text("Email: \"$(email_state[].text)\" ($(length(email_state[].text)) chars)", style=TextStyle(size_points=14, color=Vec4f(0.7, 0.7, 0.7, 1.0)))),
                    IntrinsicHeight(Fugl.Text("Phone: \"$(phone_state[].text)\" ($(length(phone_state[].text)) chars)", style=TextStyle(size_points=14, color=Vec4f(0.7, 0.7, 0.7, 1.0)))),
                ], padding=10.0, spacing=5.0),
                style=dark_container_style
            )
        ], padding=0.0, spacing=5.0),
        style=ContainerStyle(
            background_color=Vec4f(0.08, 0.08, 0.08, 1.0),
            padding=5.0f0
        )
    )
end

screenshot(MyApp, "textField.png", 812, 500);

TextField

Focus and Blur Events

TextField supports on_focus and on_blur callbacks for handling focus changes. This is useful to avoid doing bigger processing tasks for each letter change.

using Fugl

status = Ref("Field is unfocused")
text_state = Ref(EditorState("Click to focus"))

function MyApp()
    Container(
        IntrinsicColumn([
            Fugl.Text("Status: $(status[])", style=TextStyle(size_points=14, color=Vec4f(0.2, 0.6, 0.2, 1.0))),
            TextField(
                text_state[];
                on_state_change=(new_state) -> text_state[] = new_state,
                on_focus=() -> status[] = "Field is focused!",
                on_blur=() -> status[] = "Field lost focus"
            )
        ], spacing=10.0f0),
        style=ContainerStyle(padding=20.0f0, background_color=Vec4f(0.95, 0.95, 0.95, 1.0))
    )
end

screenshot(MyApp, "textfield_focus_blur.png", 812, 120);

TextField Focus Blur