liora_components/
textarea.rs1use crate::Input;
2use gpui::{
3 App, Context, Entity, FocusHandle, Focusable, Render, SharedString, Window, prelude::*, px,
4};
5use liora_core::Config;
6
7pub struct Textarea {
8 input: Entity<Input>,
9 rows: usize,
10 max_length: Option<usize>,
11 focus_handle: FocusHandle,
12}
13
14impl Textarea {
15 pub fn new(value: impl Into<SharedString>, cx: &mut Context<Self>) -> Self {
16 let value = value.into();
17 let rows = 1;
18 let input = cx.new(|cx| Input::new(value, cx).min_rows(rows));
19
20 Self {
21 input,
22 rows,
23 max_length: None,
24 focus_handle: cx.focus_handle(),
25 }
26 }
27
28 pub fn rows(mut self, rows: usize) -> Self {
29 self.rows = rows;
30 self
31 }
32
33 pub fn placeholder(self, p: impl Into<SharedString>, cx: &mut Context<Self>) -> Self {
34 self.input.update(cx, |input, cx| {
35 input.set_placeholder(p, cx);
36 });
37 self
38 }
39
40 pub fn disabled(self, d: bool, cx: &mut Context<Self>) -> Self {
41 self.input.update(cx, |input, cx| {
42 input.set_disabled(d, cx);
43 });
44 self
45 }
46
47 pub fn max_length(mut self, max: usize) -> Self {
48 self.max_length = Some(max);
49 self
50 }
51}
52
53impl Focusable for Textarea {
54 fn focus_handle(&self, _cx: &App) -> FocusHandle {
55 self.focus_handle.clone()
56 }
57}
58
59impl Render for Textarea {
60 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
61 let theme = cx.global::<Config>().theme.clone();
62 let value = self.input.read(cx).value();
63 let len = value.chars().count();
64 let rows = self.rows;
65
66 self.input.update(cx, |input, cx| {
68 if input.min_rows != rows {
69 input.set_min_rows(rows, cx);
70 }
71 });
72
73 gpui::div()
74 .flex()
75 .flex_col()
76 .gap_1()
77 .child(self.input.clone())
78 .when_some(self.max_length, |this, max| {
79 this.child(
80 gpui::div()
81 .flex()
82 .justify_end()
83 .px(px(4.0))
84 .text_size(px(theme.font_size.sm))
85 .text_color(if len > max {
86 theme.danger.base
87 } else {
88 theme.neutral.text_3
89 })
90 .child(format!("{}/{}", len, max)),
91 )
92 })
93 }
94}