gpui_component/input/
textarea.rs1use std::rc::Rc;
2
3use gpui::{
4 App, DefiniteLength, Entity, IntoElement, RenderOnce, SharedString, StyleRefinement, Styled,
5 Window, prelude::FluentBuilder as _,
6};
7
8use super::{Input, TextareaState};
9use crate::native_menu::NativeMenu;
10use crate::{RoleOverride, StyledExt as _};
11
12#[derive(IntoElement)]
14pub struct Textarea {
15 state: Entity<TextareaState>,
16 style: StyleRefinement,
17 height: Option<DefiniteLength>,
18 appearance: bool,
19 bordered: bool,
20 disabled: bool,
21 readonly: bool,
22 tab_index: isize,
23 role: RoleOverride,
24 aria_label: Option<SharedString>,
25
26 context_menu_builder: Option<Rc<dyn Fn(NativeMenu, &mut Window, &mut App) -> NativeMenu>>,
30}
31
32impl Textarea {
33 pub fn new(state: &Entity<TextareaState>) -> Self {
34 Self {
35 state: state.clone(),
36 style: StyleRefinement::default(),
37 height: None,
38 appearance: true,
39 bordered: true,
40 disabled: false,
41 readonly: false,
42 tab_index: 0,
43 role: RoleOverride::default(),
44 aria_label: None,
45 context_menu_builder: None,
46 }
47 }
48
49 pub fn h(mut self, height: impl Into<DefiniteLength>) -> Self {
50 self.height = Some(height.into());
51 self
52 }
53
54 pub fn appearance(mut self, appearance: bool) -> Self {
55 self.appearance = appearance;
56 self
57 }
58
59 pub fn bordered(mut self, bordered: bool) -> Self {
60 self.bordered = bordered;
61 self
62 }
63
64 pub fn disabled(mut self, disabled: bool) -> Self {
65 self.disabled = disabled;
66 self
67 }
68
69 pub fn readonly(mut self, readonly: bool) -> Self {
75 self.readonly = readonly;
76 self
77 }
78
79 pub fn tab_index(mut self, index: isize) -> Self {
80 self.tab_index = index;
81 self
82 }
83
84 pub fn role(mut self, role: impl Into<RoleOverride>) -> Self {
85 self.role = role.into();
86 self
87 }
88
89 pub fn aria_label(mut self, label: impl Into<SharedString>) -> Self {
90 self.aria_label = Some(label.into());
91 self
92 }
93
94 pub fn context_menu(
99 mut self,
100 f: impl Fn(NativeMenu, &mut Window, &mut App) -> NativeMenu + 'static,
101 ) -> Self {
102 self.context_menu_builder = Some(Rc::new(f));
103 self
104 }
105}
106
107impl Styled for Textarea {
108 fn style(&mut self) -> &mut StyleRefinement {
109 &mut self.style
110 }
111}
112
113impl RenderOnce for Textarea {
114 fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
115 Input::from_state(self.state.clone())
116 .appearance(self.appearance)
117 .bordered(self.bordered)
118 .disabled(self.disabled)
119 .readonly(self.readonly)
120 .tab_index(self.tab_index)
121 .role(self.role)
122 .when_some(self.height, |this, height| this.h(height))
123 .when_some(self.aria_label, |this, label| this.aria_label(label))
124 .when_some(self.context_menu_builder, |this, build| {
125 this.context_menu(move |menu, window, cx| build(menu, window, cx))
126 })
127 .refine_style(&self.style)
128 }
129}