Skip to main content

cloudflare_dns/ui/components/
form_field.rs

1use crate::ui::colors::{BLUE, OVERLAY1, SURFACE0, TEAL, TEXT};
2use crate::ui::state::FormFieldProps;
3use iocraft::prelude::*;
4
5#[component]
6pub fn FormField(props: &FormFieldProps, _hooks: Hooks) -> impl Into<AnyElement<'static>> {
7    let Some(mut value) = props.value else {
8        // Graceful fallback: render a disabled-looking field
9        return element! {
10            View(flex_direction: FlexDirection::Row, margin_bottom: 1, align_items: AlignItems::Center) {
11                View(width: 12) { Text(content: format!("{}: ", props.label), color: TEAL) }
12                View(
13                    border_style: BorderStyle::None,
14                    padding: 1,
15                    width: 40,
16                    background_color: SURFACE0,
17                ) {
18                    Text(content: "(no value)", color: OVERLAY1)
19                }
20            }
21        };
22    };
23
24    let field_content = if props.is_editable {
25        element! {
26            TextInput(
27                has_focus: props.has_focus,
28                value: value.to_string(),
29                on_change: move |new_value| value.set(new_value),
30            )
31        }
32        .into_any()
33    } else {
34        element! {
35            Text(content: value.to_string(), color: TEXT, weight: Weight::Bold)
36        }
37        .into_any()
38    };
39
40    element! {
41        View(flex_direction: FlexDirection::Row, margin_bottom: 1, align_items: AlignItems::Center) {
42            View(width: 12) {
43                Text(content: format!("{}: ", props.label), color: TEAL)
44            }
45            View(
46                border_style: if props.has_focus { BorderStyle::Round } else { BorderStyle::None },
47                border_color: BLUE,
48                padding: if props.has_focus { 0 } else { 1 },
49                width: 40,
50                background_color: SURFACE0,
51            ) {
52                #(field_content)
53            }
54            View(margin_left: 1) {
55                Text(content: props.suffix.clone(), color: OVERLAY1)
56            }
57        }
58    }
59}