Textarea
Write a message with a themed multiline field.

use blinc_cn as cn;
use blinc_core::reactive::{Signal, computed};
use blinc_layout::{binding::IntoReactive, prelude::*};
pub fn textarea_demo(
name: Signal<String>,
multiline: blinc_layout::widgets::text_area::SharedTextAreaState,
disabled: Signal<bool>,
) -> Div {
div()
.class("demo-wide")
.child(
cn::textarea(&multiline)
.label("Your message")
.placeholder("Tell us what you are building…")
.rows(4)
.disabled(disabled)
.on_change(move |text| name.set(text.to_string())),
)
.child(
bound_text(computed(move |g| {
format!("{} characters", g.get(name).unwrap_or_default().chars().count())
}))
.class("demo-caption"),
)
}
fn bound_text(value: impl IntoReactive<String>) -> Text {
Text::bound(value.into_reactive())
}
@layer components {
.blinc-ime-composition {
text-decoration: underline;
}
.cn-textarea {
font-family: var(--font-sans);
}
.cn-textarea {
letter-spacing: var(--tracking-tight);
}
.cn-textarea:disabled {
box-shadow: none;
}
.cn-textarea {
box-shadow: var(--shadow-sm);
background: var(--cn-textarea-bg, var(--input-bg));
border-color: var(--border);
border-radius: var(--radius-default);
color: var(--text-primary);
outline: 2px solid transparent;
outline-offset: 1px;
transition:
background-color var(--duration-fast) var(--ease-state),
border-color var(--duration-fast) var(--ease-state),
outline-color var(--duration-fast) var(--ease-state),
outline-offset var(--duration-fast) var(--ease-out);
}
.cn-textarea:focus:not(:disabled) {
outline: 2px solid var(--focus-ring);
outline-offset: 2px;
}
.cn-textarea[data-invalid]:not(:disabled),
.cn-textarea[data-invalid]:hover:not(:disabled),
.cn-textarea[data-invalid]:focus:not(:disabled) {
border-color: var(--border-error);
}
.cn-textarea[data-invalid]:focus:not(:disabled) {
outline: 2px solid var(--focus-ring-error);
}
.cn-textarea.cn-textarea--success:not(:disabled),
.cn-textarea.cn-textarea--success:hover:not(:disabled),
.cn-textarea.cn-textarea--success:focus:not(:disabled) {
border-color: var(--success);
}
.cn-textarea.cn-textarea--success:focus:not(:disabled) {
outline: 2px solid var(--focus-ring-success);
}
}
Usage and properties
Write a message with a themed multiline field. Apply CSS after the component layer to restyle the documented parts.
Use the installation guide to add blinc_cn and its component stylesheet. Create the fixture bindings once, and return the demo from your UI builder. Values marked Bound accept Signal/Computed sources where the API supports them; structural options configure the component at construction.
| Property | Type | Update model | This example |
|---|---|---|---|
document | SharedTextAreaState | Shared document | values.multiline |
rows / placeholder | usize / string | Construction | 4 / Tell us what you are building… |
on_change | Fn(&str) | Callback | Updates the character count |
disabled | bool or IntoReactive<bool> | Bound | values.disabled |
Keyboard and interaction
Tab focuses the field and the next Tab leaves it. Typing, arrow keys, selection and clipboard shortcuts apply; Enter inserts a new line. :focus-visible marks keyboard focus.
Customizing it
Add application CSS after the default component layer. These selectors are the restyling surface for this component:
.cn-textarea.blinc-ime-composition
Theme and component variables: --primary, --text-primary, --text-secondary, --surface, --border, --radius-default, --duration-fast, --ease-state.
Built-in themes
The Live theme control installs Blinc's own theme bundles, including their colours, focus rings, corner shapes and motion tokens.
pub fn theme_bundle_for(name: &str) -> blinc_theme::ThemeBundle {
match name {
"restrained" => blinc_theme::RestrainedTheme::bundle(),
"expressive" => blinc_theme::ExpressiveTheme::bundle(),
_ => blinc_theme::HybridTheme::bundle(),
}
.with_css(blinc_cn::cn_styles::CN_STYLES)
}Download the default widget and component stylesheets. Sample assets and licenses are available in the asset guide.
Documentation
From the canonical component guide.
Multi-line text input, bound to a SharedTextAreaState:
use blinc::layout::widgets::text_area::text_area_state;
let description = text_area_state();
cn::textarea(&description)
.label("Description")
.placeholder("Enter description...")
.rows(4)
.on_change(|value| println!("description: {value}"))
.error("msg") shows the message and turns the border red; .disabled(true)
dims the field. The message under a field is .cn-field-error, or
.cn-field-description for .description(..), coloured by those rules. It is styled like Input: one element with the class
cn-textarea, whose border and fill per state are :hover, :focus,
[data-invalid] and :disabled rules, eased by a transition. Its
placeholder, description and error follow signals as an input's do.
Platforms and version
The component API is available in Blinc 0.6.0. The Live example runs in a dedicated worker and requires a compatible GPU surface. Preview and Code remain available when Live cannot start. The canvas has a descriptive label; a full screen-reader DOM mirror is not provided. The gallery integration is based on revision e2e55c24e078.
Recordings and live demos use the default Hybrid theme with bundled Noto Sans. The recording uses a 560 × 320 logical viewport at twice that resolution. Live follows its container and actual display density. Source base revision · Exact build source · Artifact versions and checksums · Font license.