use crate::core::types::FieldValue;
use leptos::prelude::*;
#[component]
pub fn CodeInput(
#[prop(into)]
name: String,
#[prop(into)]
value: Signal<FieldValue>,
#[prop(into)]
_on_change: Callback<FieldValue>,
#[prop(optional, into)]
placeholder: Option<String>,
#[prop(optional)]
required: Option<bool>,
#[prop(optional)]
disabled: Option<bool>,
#[prop(optional, into)]
class: Option<String>,
#[prop(optional, into)]
error: Option<String>,
#[prop(optional)]
has_error: Option<bool>,
#[prop(optional, into)]
_language: Option<String>,
#[prop(optional)]
show_line_numbers: Option<bool>,
#[prop(optional)]
show_language_selector: Option<bool>,
#[prop(optional)]
show_fullscreen: Option<bool>,
#[prop(optional)]
min_height: Option<u32>,
#[prop(optional)]
max_height: Option<u32>,
) -> impl IntoView {
let show_line_numbers = show_line_numbers.unwrap_or(true);
let show_language_selector = show_language_selector.unwrap_or(true);
let _show_fullscreen = show_fullscreen.unwrap_or(true);
let min_height = min_height.unwrap_or(200);
let max_height = max_height.unwrap_or(600);
let current_value = move || match value.get() {
FieldValue::String(s) => s,
_ => String::new(),
};
let supported_languages = vec![
("rust", "Rust"),
("javascript", "JavaScript"),
("typescript", "TypeScript"),
("python", "Python"),
("java", "Java"),
("cpp", "C++"),
("c", "C"),
("go", "Go"),
("html", "HTML"),
("css", "CSS"),
("sql", "SQL"),
("json", "JSON"),
("yaml", "YAML"),
("toml", "TOML"),
("markdown", "Markdown"),
];
let language_selector_view = move || {
if show_language_selector {
Some(view! {
<select class="language-selector">
{supported_languages.iter().map(|(value, label)| {
view! {
<option value={*value}>{*label}</option>
}
}).collect::<Vec<_>>()}
</select>
})
} else {
None
}
};
let error_view = move || {
error.as_ref().map(|error_msg| {
view! {
<div class="error-message">
{error_msg.clone()}
</div>
}
})
};
view! {
<div class={format!("code-input {}", class.unwrap_or_default())}>
<div class="code-toolbar">
{language_selector_view}
<div class="toolbar-actions">
<button type="button" class="toolbar-btn">"📋"</button>
<button type="button" class="toolbar-btn">"💾"</button>
<button type="button" class="toolbar-btn">"📝"</button>
<button type="button" class="toolbar-btn">"🔍"</button>
<button type="button" class="toolbar-btn">"⚙️"</button>
<button type="button" class="toolbar-btn">"⛶"</button>
</div>
</div>
<div class="code-editor-container">
<textarea
name={name.clone()}
placeholder={placeholder}
required={required}
disabled={disabled}
class={move || {
let mut classes = vec!["code-textarea"];
if has_error.unwrap_or(false) {
classes.push("error");
}
if disabled.unwrap_or(false) {
classes.push("disabled");
}
if show_line_numbers {
classes.push("with-line-numbers");
}
classes.join(" ")
}}
style={format!("min-height: {}px; max-height: {}px;", min_height, max_height)}
>{current_value}</textarea>
</div>
{error_view}
</div>
}
}