orbit/kit/components/
input.rs

1// Input component for OrbitKit
2
3use crate::component::{Component, ComponentError, ComponentId, Context, Node};
4
5/// Input component
6#[derive(Debug)]
7pub struct Input {
8    /// Component ID for tracking
9    id: ComponentId,
10    /// Input type (text, password, email, etc.)
11    pub input_type: String,
12    /// Input value
13    pub value: String,
14    /// Input placeholder
15    pub placeholder: Option<String>,
16    /// Whether the input is disabled
17    pub disabled: bool,
18    /// Whether the input is required
19    pub required: bool,
20    /// Input label
21    pub label: Option<String>,
22    /// Input error message
23    pub error: Option<String>,
24    /// Input helper text
25    pub helper_text: Option<String>,
26    /// On change handler
27    pub on_change: Option<fn(String)>,
28}
29
30/// Input props
31#[derive(Debug, Clone)]
32pub struct InputProps {
33    /// Input type (text, password, email, etc.)
34    pub input_type: Option<String>,
35    /// Input value
36    pub value: String,
37    /// Input placeholder
38    pub placeholder: Option<String>,
39    /// Whether the input is disabled
40    pub disabled: Option<bool>,
41    /// Whether the input is required
42    pub required: Option<bool>,
43    /// Input label
44    pub label: Option<String>,
45    /// Input error message
46    pub error: Option<String>,
47    /// Input helper text
48    pub helper_text: Option<String>,
49    /// On change handler
50    pub on_change: Option<fn(String)>,
51}
52
53impl Default for Input {
54    fn default() -> Self {
55        Self {
56            id: ComponentId::new(),
57            input_type: "text".to_string(),
58            value: String::new(),
59            placeholder: None,
60            disabled: false,
61            required: false,
62            label: None,
63            error: None,
64            helper_text: None,
65            on_change: None,
66        }
67    }
68}
69
70impl Component for Input {
71    type Props = InputProps;
72
73    fn component_id(&self) -> ComponentId {
74        self.id
75    }
76
77    fn create(props: Self::Props, _context: Context) -> Self {
78        Self {
79            id: ComponentId::new(),
80            input_type: props.input_type.unwrap_or_else(|| "text".to_string()),
81            value: props.value,
82            placeholder: props.placeholder,
83            disabled: props.disabled.unwrap_or(false),
84            required: props.required.unwrap_or(false),
85            label: props.label,
86            error: props.error,
87            helper_text: props.helper_text,
88            on_change: props.on_change,
89        }
90    }
91
92    fn update(&mut self, props: Self::Props) -> Result<(), ComponentError> {
93        self.input_type = props.input_type.unwrap_or_else(|| self.input_type.clone());
94        self.value = props.value;
95        self.placeholder = props.placeholder;
96        self.disabled = props.disabled.unwrap_or(self.disabled);
97        self.required = props.required.unwrap_or(self.required);
98        self.label = props.label;
99        self.error = props.error;
100        self.helper_text = props.helper_text;
101        self.on_change = props.on_change;
102        Ok(())
103    }
104
105    fn as_any(&self) -> &dyn std::any::Any {
106        self
107    }
108
109    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
110        self
111    }
112
113    fn render(&self) -> Result<Vec<Node>, ComponentError> {
114        // For now, return an empty Vec since we're not yet using the Node system
115        // In a real implementation, this would return the actual DOM nodes
116        Ok(vec![])
117    }
118}