Skip to main content

teksilo_core/styles/
text_input_style.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Tier-3 style protocol for `TextInput`. See `docs/styling-system.md`.
5
6use std::rc::Rc;
7
8use serde::{Deserialize, Serialize};
9
10use crate::build_context::BuildContext;
11use crate::signal::Signal;
12use crate::widget_id::WidgetId;
13
14#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default, Serialize, Deserialize)]
15pub enum TextInputVariant {
16    /// IntUI default: 1 dp bordered rectangle.
17    #[default]
18    Outlined,
19    /// Filled background, no border (Material-3-ish).
20    Filled,
21    /// Just a baseline underline.
22    Underline,
23    /// No chrome at all — for embedded fields where the parent
24    /// surface IS the chrome (search fields, ComboBox text part).
25    Bare,
26}
27
28/// Validation outcome state, separate from interaction state. Drives
29/// border-color tinting and the per-state recipe lookup independently
30/// of focus/hover.
31#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default, Serialize, Deserialize)]
32pub enum TextInputValidationLevel {
33    #[default]
34    None,
35    Info,
36    Warning,
37    Error,
38    /// Brief accent tint after a successful auto-correction.
39    Corrected,
40}
41
42#[derive(Clone, Debug)]
43pub struct TextInputStyleConfig {
44    /// The actual editable area subtree (caret, glyph layout, IME).
45    /// The style wraps it with border / fill / focus-ring chrome.
46    pub editor: WidgetId,
47    pub is_focused: Signal<bool>,
48    pub is_hovered: Signal<bool>,
49    pub is_disabled: Signal<bool>,
50    pub validation: Signal<TextInputValidationLevel>,
51    pub variant: TextInputVariant,
52}
53
54pub trait TextInputStyle: 'static {
55    fn make_body(&self, cfg: &TextInputStyleConfig, ctx: &mut BuildContext) -> WidgetId;
56}
57
58pub type SharedTextInputStyle = Rc<dyn TextInputStyle>;