Skip to content

Commit 198b437

Browse files
committed
feat(leptos): add search input component
1 parent 3ea9b45 commit 198b437

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed

crates/leptos/src/input.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ use components_core::{BASE_CLASS, concat};
22
use leptos::prelude::*;
33
use leptos::{IntoView, component, view};
44

5+
mod search;
6+
7+
pub use search::{Filter, InputSearch};
8+
59
#[component]
610
pub fn Input(
711
#[prop(into)] has_error: ReadSignal<bool>,

crates/leptos/src/input/search.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
use leptos::{IntoView, component, view};
4+
5+
use crate::icons::{Filter as FilterIcon, Search as SearchIcon};
6+
use crate::tag::Tag;
7+
8+
#[derive(Clone, Debug)]
9+
pub struct Filter {
10+
pub label: String,
11+
pub value: String,
12+
}
13+
14+
#[component]
15+
pub fn InputSearch(
16+
#[prop(into, optional)] filters: Option<Vec<Filter>>,
17+
#[prop(into, optional)] active_filters: Vec<Filter>,
18+
#[prop(into)] on_change_filter: Callback<Vec<Filter>, ()>,
19+
) -> impl IntoView {
20+
let (filter_modal, set_filter_modal) = signal(false);
21+
let has_filter = filters.as_ref().map_or(false, |f| !f.is_empty());
22+
23+
let handle_select_filter = {
24+
let active_filters = active_filters.clone();
25+
26+
move |filter: Filter, is_selected: bool| {
27+
if !is_selected {
28+
let mut new_filters = active_filters.clone();
29+
new_filters.push(filter);
30+
on_change_filter.run(new_filters);
31+
} else {
32+
let new_filters = active_filters
33+
.iter()
34+
.filter(|f| f.value != filter.value)
35+
.cloned()
36+
.collect();
37+
on_change_filter.run(new_filters);
38+
}
39+
}
40+
};
41+
42+
let handle_close_on_click_input = move || {
43+
if has_filter {
44+
set_filter_modal.set(false);
45+
}
46+
};
47+
48+
view! {
49+
<div class=concat!(BASE_CLASS, "-input-search-container")>
50+
<label
51+
class=crate::tw!(
52+
concat!(BASE_CLASS, "-input-search"),
53+
has_filter.then_some(concat!(BASE_CLASS, "-input-search--filter"))
54+
)
55+
>
56+
<SearchIcon size=24u32 />
57+
<input
58+
type="text"
59+
placeholder="Buscar"
60+
on:click=move |_| handle_close_on_click_input()
61+
class="text-caption"
62+
/>
63+
</label>
64+
<div class=concat!(BASE_CLASS, "-input-search__filter")>
65+
{has_filter.then(|| view! {
66+
<button on:click=move |_| set_filter_modal.update(|v| *v = !*v) tabindex="0">
67+
<FilterIcon size=24u32 />
68+
</button>
69+
})}
70+
<div
71+
class=crate::tw!(
72+
concat!(BASE_CLASS, "-input-search-backdrop__content"),
73+
filter_modal.get().then_some(concat!(BASE_CLASS, "-input-search-backdrop__content--open"))
74+
.unwrap_or(concat!(BASE_CLASS, "-input-search-backdrop__content--closed"))
75+
)
76+
>
77+
{filter_modal.get().then(|| {
78+
view! {
79+
<ul class=concat!(BASE_CLASS, "-input-search-backdrop__list")>
80+
{filters.map(|filters| filters.iter().map(|filter| {
81+
let is_selected = active_filters.iter().any(|f| f.value == filter.value);
82+
let filter = filter.clone();
83+
let handle_select_filter = handle_select_filter.clone();
84+
view! {
85+
<li
86+
on:click=move |_| handle_select_filter(filter.clone(), is_selected)
87+
>
88+
<Tag
89+
selected=is_selected
90+
label=filter.label.clone()
91+
/>
92+
</li>
93+
}
94+
}).collect::<Vec<_>>()).unwrap_or_default()}
95+
</ul>
96+
}})}
97+
</div>
98+
</div>
99+
</div>
100+
}
101+
}

crates/leptos/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub mod prelude {
2424
pub use crate::card::Card;
2525
pub use crate::chip::{Chip, Variant as ChipVariant};
2626
pub use crate::flap::Flap;
27-
pub use crate::input::Input;
27+
pub use crate::input::{Filter as SearchFilter, Input, InputSearch};
2828
pub use crate::level::{Level, Variant as LevelVariant};
2929
pub use crate::progress_bar::ProgressBar;
3030
pub use crate::tag::Tag;

0 commit comments

Comments
 (0)