logicaffeine_web/ui/components/
inline_editor.rs1use dioxus::prelude::*;
15
16use super::code_editor::{CodeEditor, Language, CODE_EDITOR_STYLE};
17
18const INLINE_EDITOR_STYLE: &str = r#"
19.inline-editor .code-editor {
20 height: auto;
21 background: transparent;
22}
23.inline-editor .code-editor-input {
24 flex: none;
25 min-height: 0;
26}
27.inline-editor .code-editor-highlight {
28 position: relative;
29 height: auto;
30 overflow: hidden;
31 padding-bottom: 16px;
32}
33/* A new line at the very end is a line the reader sees at once: the space holds it open. */
34.inline-editor .code-editor-highlight::after {
35 content: " ";
36}
37.inline-editor .code-editor-textarea {
38 overflow: hidden;
39 padding-bottom: 16px;
40}
41@media (max-width: 768px) {
42 .inline-editor .code-editor-highlight,
43 .inline-editor .code-editor-textarea {
44 padding-bottom: 12px;
45 }
46}
47"#;
48
49#[component]
51pub fn InlineEditorStyle() -> Element {
52 rsx! {
53 style { "{CODE_EDITOR_STYLE}" }
54 style { "{INLINE_EDITOR_STYLE}" }
55 }
56}
57
58#[component]
59pub fn InlineEditor(
60 value: String,
61 on_change: EventHandler<String>,
62 language: Language,
63 #[props(default = false)]
64 readonly: bool,
65) -> Element {
66 let mut seen = use_signal(|| false);
67
68 rsx! {
69 div {
70 class: "inline-editor",
71 onvisible: move |evt| {
72 if !*seen.peek() && evt.data().is_intersecting().unwrap_or(false) {
73 seen.set(true);
74 }
75 },
76 CodeEditor {
77 value,
78 on_change,
79 language,
80 readonly,
81 language_server: seen(),
82 placeholder: String::new(),
83 stylesheet: false,
84 }
85 }
86 }
87}
88
89#[cfg(test)]
90#[path = "../../../../../crates/logicaffeine_tests/unit/logicaffeine_web/ui/components/inline_editor/tests.rs"]
91mod tests;