polyhorn_ios/components/
text_input.rs1use polyhorn_core::CommandBuffer;
2use polyhorn_ios_sys::coregraphics::CGRect;
3use polyhorn_ios_sys::polykit::{PLYTextInputView, PLYView};
4use polyhorn_ui::styles::TextStyle;
5
6use crate::prelude::*;
7use crate::raw::{attributed_string, Builtin, Container, ContainerID, OpaqueContainer};
8use crate::{Key, Reference};
9
10#[derive(Default)]
12pub struct TextInput {
13 pub placeholder: String,
15
16 pub placeholder_style: TextStyle,
18}
19
20impl Container for PLYTextInputView {
21 fn mount(&mut self, child: &mut OpaqueContainer) {
22 if let Some(view) = child.container().to_view() {
23 PLYTextInputView::to_view(self).add_subview(&view)
24 }
25 }
26
27 fn unmount(&mut self) {
28 PLYTextInputView::to_view(self).remove_from_superview();
29 }
30
31 fn to_view(&self) -> Option<PLYView> {
32 Some(PLYTextInputView::to_view(self))
33 }
34}
35
36impl Component for TextInput {
37 fn render(&self, manager: &mut Manager) -> Element {
38 let view_ref: Reference<Option<ContainerID>> = use_reference!(manager, None);
39
40 let placeholder = self.placeholder.clone();
41 let placeholder_style = self.placeholder_style.clone();
42
43 use_layout_effect!(manager, move |link, buffer| {
44 let id = match view_ref.apply(link, |&mut id| id) {
45 Some(id) => id,
46 None => return,
47 };
48
49 buffer.mutate(&[id], move |containers, _| {
50 let container = &mut containers[0];
51
52 let layout = match container.layout() {
53 Some(layout) => layout.clone(),
54 None => return,
55 };
56
57 assert!(container.downcast_mut::<PLYTextInputView>().is_some());
58
59 if let Some(view) = container.downcast_mut::<PLYTextInputView>() {
60 view.set_attributed_placeholder(&attributed_string(
61 &placeholder,
62 &placeholder_style,
63 ));
64
65 view.to_view().set_layout(move || {
66 let current = layout.current();
67
68 CGRect::new(
69 current.origin.x as _,
70 current.origin.y as _,
71 current.size.width as _,
72 current.size.height as _,
73 )
74 });
75 }
76 });
77 });
78
79 Element::builtin(
80 Key::new(()),
81 Builtin::TextInput,
82 manager.children(),
83 Some(view_ref.weak(manager)),
84 )
85 }
86}