use leptos::prelude::*;
use leptos::text_prop::TextProp;
use lepticons::{Icon, LucideGlyph};
#[component]
pub fn IconSearch(
#[prop(into)]
value: Signal<String>,
on_change: Callback<String>,
#[prop(default = 150)]
debounce_ms: u64,
#[prop(into, optional)]
placeholder: Option<TextProp>,
#[prop(into, optional)]
class: Option<TextProp>,
#[prop(default = true)]
show_clear: bool,
) -> impl IntoView {
let placeholder = placeholder.unwrap_or_else(|| "Search icons...".into());
let pending_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
let on_input = move |ev: leptos::ev::Event| {
let new_value = event_target_value(&ev);
if let Some(handle) = pending_handle.get_value() {
handle.clear();
}
let handle = set_timeout_with_handle(
move || on_change.run(new_value),
std::time::Duration::from_millis(debounce_ms),
)
.ok();
pending_handle.set_value(handle);
};
let clear = move |_| {
if let Some(handle) = pending_handle.get_value() {
handle.clear();
}
on_change.run(String::new());
};
let container_style = "display:flex;align-items:center;gap:0.5rem;\
padding:0.5rem 1rem;\
background:var(--lp-bg,#f5f5f5);\
border-radius:var(--lp-radius,0.5rem);\
border:1px solid var(--lp-border,#e5e5e5)";
let input_style = "flex:1;background:transparent;border:none;outline:none;\
color:var(--lp-text,inherit);font-size:0.875rem";
view! {
<div class=move || class.as_ref().map(|c| c.get().to_string()).unwrap_or_default()
style=container_style>
<Icon glyph=LucideGlyph::Search size="18"
stroke="var(--lp-text-muted,#999)" />
<input type="text"
style=input_style
prop:placeholder=move || placeholder.get()
prop:value=move || value.get()
on:input=on_input
/>
{move || (show_clear && !value.get().is_empty()).then(|| view! {
<span style="cursor:pointer;display:flex" on:click=clear>
<Icon glyph=LucideGlyph::X size="16"
stroke="var(--lp-text-muted,#999)" />
</span>
})}
</div>
}
}