Skip to main content

ansiq_widgets/
composer_bar.rs

1use ansiq_core::{ChangeHandler, Element, Layout, Length, Style, SubmitHandler};
2
3use crate::{Box, Input, Text};
4
5pub struct ComposerBar<Message = ()> {
6    value: String,
7    placeholder: String,
8    meta: Option<String>,
9    on_change: Option<ChangeHandler>,
10    on_submit: Option<SubmitHandler<Message>>,
11    input_style: Style,
12    meta_style: Style,
13}
14
15impl ComposerBar<()> {
16    pub fn new() -> Self {
17        Self {
18            value: String::new(),
19            placeholder: String::new(),
20            meta: None,
21            on_change: None,
22            on_submit: None,
23            input_style: Style::default(),
24            meta_style: Style::default(),
25        }
26    }
27}
28
29impl<Message: 'static> ComposerBar<Message> {
30    pub fn value(mut self, value: impl Into<String>) -> Self {
31        self.value = value.into();
32        self
33    }
34
35    pub fn placeholder(mut self, placeholder: impl Into<String>) -> Self {
36        self.placeholder = placeholder.into();
37        self
38    }
39
40    pub fn meta(mut self, meta: impl Into<String>) -> Self {
41        self.meta = Some(meta.into());
42        self
43    }
44
45    pub fn on_change<F>(mut self, handler: F) -> Self
46    where
47        F: FnMut(String) + 'static,
48    {
49        self.on_change = Some(std::boxed::Box::new(handler));
50        self
51    }
52
53    pub fn on_submit<NextMessage, F>(self, handler: F) -> ComposerBar<NextMessage>
54    where
55        F: FnMut(String) -> Option<NextMessage> + 'static,
56    {
57        ComposerBar {
58            value: self.value,
59            placeholder: self.placeholder,
60            meta: self.meta,
61            on_change: self.on_change,
62            on_submit: Some(std::boxed::Box::new(handler)),
63            input_style: self.input_style,
64            meta_style: self.meta_style,
65        }
66    }
67
68    pub fn input_style(mut self, style: Style) -> Self {
69        self.input_style = style;
70        self
71    }
72
73    pub fn meta_style(mut self, style: Style) -> Self {
74        self.meta_style = style;
75        self
76    }
77
78    pub fn build(self) -> Element<Message> {
79        let mut column = Box::column().gap(0).layout(Layout {
80            width: Length::Fill,
81            height: Length::Auto,
82        });
83
84        let input = Input::new()
85            .value(self.value)
86            .placeholder(self.placeholder)
87            .style(self.input_style);
88        let input = if let Some(handler) = self.on_change {
89            input.on_change(handler)
90        } else {
91            input
92        };
93        let input = if let Some(handler) = self.on_submit {
94            input.on_submit(handler)
95        } else {
96            input.on_submit(|_| None::<Message>)
97        };
98        column = column.child(input.build());
99
100        if let Some(meta) = self.meta {
101            column = column.child(Text::new(meta).style(self.meta_style).build());
102        }
103
104        column.build()
105    }
106}