Skip to main content

desktop_example/app/routes/
editor.rs

1use freya::{
2    code_editor::*,
3    prelude::*,
4    text_edit::Rope,
5};
6
7const SAMPLE_CODE: &str = r#"use freya::prelude::*;
8
9fn app() -> impl IntoElement {
10    let mut count = use_state(|| 0);
11    let is_positive = *count.read() >= 0;
12
13    rect()
14        .expanded()
15        .center()
16        .spacing(12.)
17        .child(
18            rect()
19                .width(Size::px(250.))
20                .height(Size::px(120.))
21                .center()
22                .background(if is_positive {
23                    (15, 163, 242)
24                } else {
25                    (220, 50, 50)
26                })
27                .corner_radius(16.)
28                .color(Color::WHITE)
29                .font_size(56.)
30                .font_weight(FontWeight::BOLD)
31                .shadow((0., 4., 20., 4., (0, 0, 0, 80)))
32                .child(count.read().to_string()),
33        )
34        .child(
35            rect()
36                .horizontal()
37                .spacing(8.)
38                .child(
39                    Button::new()
40                        .filled()
41                        .on_press(move |_| {
42                            *count.write() -= 1;
43                        })
44                        .child("Decrease"),
45                )
46                .child(
47                    Button::new()
48                        .on_press(move |_| {
49                            count.set(0);
50                        })
51                        .child("Reset"),
52                )
53                .child(
54                    Button::new()
55                        .filled()
56                        .on_press(move |_| {
57                            *count.write() += 1;
58                        })
59                        .child("Increase"),
60                ),
61        )
62}
63
64#[derive(PartialEq)]
65struct TodoItem {
66    label: String,
67    done: bool,
68}
69
70#[derive(PartialEq)]
71struct TodoList;
72
73impl Component for TodoList {
74    fn render(&self) -> impl IntoElement {
75        let mut items = use_state::<Vec<TodoItem>>(Vec::new);
76        let mut input = use_state(String::new);
77
78        let on_submit = move |_| {
79            let text = input.read().trim().to_string();
80            if !text.is_empty() {
81                items.write().push(TodoItem {
82                    label: text,
83                    done: false,
84                });
85                input.set(String::new());
86            }
87        };
88
89        rect()
90            .width(Size::px(400.))
91            .spacing(8.)
92            .padding(16.)
93            .child(
94                rect()
95                    .horizontal()
96                    .spacing(8.)
97                    .child(
98                        Input::new()
99                            .value(input.read().clone())
100                            .on_change(move |txt| input.set(txt))
101                            .placeholder("Add a task..."),
102                    )
103                    .child(
104                        Button::new()
105                            .filled()
106                            .on_press(on_submit)
107                            .child("Add"),
108                    ),
109            )
110            .children(
111                items
112                    .read()
113                    .iter()
114                    .enumerate()
115                    .map(|(idx, item)| {
116                        let label = if item.done {
117                            format!("[x] {}", item.label)
118                        } else {
119                            format!("[ ] {}", item.label)
120                        };
121
122                        Button::new()
123                            .flat()
124                            .on_press(move |_| {
125                                items.write()[idx].done =
126                                    !items.read()[idx].done;
127                            })
128                            .child(label)
129                            .into()
130                    })
131                    .collect::<Vec<_>>(),
132            )
133    }
134}"#;
135
136#[derive(PartialEq)]
137pub struct EditorDemo;
138
139impl Component for EditorDemo {
140    fn render(&self) -> impl IntoElement {
141        let focus = use_focus();
142
143        let editor = use_state(move || {
144            let rope = Rope::from_str(SAMPLE_CODE);
145            let mut editor = CodeEditorData::new(rope, LanguageId::Rust);
146            editor.set_theme(SyntaxTheme::default());
147            editor.parse();
148            editor.measure(14., "Jetbrains Mono");
149            editor
150        });
151
152        rect()
153            .expanded()
154            .padding(8.)
155            .child(CodeEditor::new(editor, focus.a11y_id()).line_height(1.3))
156    }
157}