mirror of
https://github.com/adoyle0/thaw.git
synced 2025-03-13 05:59:49 -04:00
* feat: alert, avatar, badge option * feat: some component option * feat: add OptionalProp * feat: some component option * feat: some component option
93 lines
3.1 KiB
Rust
93 lines
3.1 KiB
Rust
mod panel;
|
|
mod theme;
|
|
|
|
use crate::{
|
|
chrono::NaiveDate,
|
|
components::{Binder, Follower, FollowerPlacement},
|
|
utils::{mount_style, now_date, ComponentRef, Model, OptionalProp},
|
|
Icon, Input, InputSuffix, SignalWatch,
|
|
};
|
|
use leptos::*;
|
|
use panel::{Panel, PanelRef};
|
|
pub use theme::DatePickerTheme;
|
|
|
|
#[component]
|
|
pub fn DatePicker(
|
|
#[prop(optional, into)] value: Model<Option<NaiveDate>>,
|
|
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
|
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
|
|
) -> impl IntoView {
|
|
mount_style("date-picker", include_str!("./date-picker.css"));
|
|
let date_picker_ref = create_node_ref::<html::Div>();
|
|
let is_show_panel = create_rw_signal(false);
|
|
let show_date_text = create_rw_signal(String::new());
|
|
let show_date_format = "%Y-%m-%d";
|
|
let update_show_date_text = move || {
|
|
value.with_untracked(move |date| {
|
|
let text = date.as_ref().map_or(String::new(), |date| {
|
|
date.format(show_date_format).to_string()
|
|
});
|
|
show_date_text.set(text);
|
|
});
|
|
};
|
|
update_show_date_text();
|
|
let panel_ref = ComponentRef::<PanelRef>::default();
|
|
let panel_selected_date = create_rw_signal(None::<NaiveDate>);
|
|
_ = panel_selected_date.watch(move |date| {
|
|
let text = date.as_ref().map_or(String::new(), |date| {
|
|
date.format(show_date_format).to_string()
|
|
});
|
|
show_date_text.set(text);
|
|
});
|
|
|
|
let on_input_blur = Callback::new(move |_| {
|
|
if let Ok(date) =
|
|
NaiveDate::parse_from_str(&show_date_text.get_untracked(), show_date_format)
|
|
{
|
|
if value.get_untracked() != Some(date) {
|
|
value.set(Some(date));
|
|
update_show_date_text();
|
|
}
|
|
} else {
|
|
update_show_date_text();
|
|
}
|
|
});
|
|
|
|
let close_panel = Callback::new(move |date: Option<NaiveDate>| {
|
|
if value.get_untracked() != date {
|
|
if date.is_some() {
|
|
value.set(date);
|
|
}
|
|
update_show_date_text();
|
|
}
|
|
is_show_panel.set(false);
|
|
});
|
|
|
|
let open_panel = Callback::new(move |_| {
|
|
panel_selected_date.set(value.get_untracked());
|
|
if let Some(panel_ref) = panel_ref.get_untracked() {
|
|
panel_ref.init_panel(value.get_untracked().unwrap_or(now_date()));
|
|
}
|
|
is_show_panel.set(true);
|
|
});
|
|
|
|
view! {
|
|
<Binder target_ref=date_picker_ref>
|
|
<div ref=date_picker_ref>
|
|
<Input attrs class value=show_date_text on_focus=open_panel on_blur=on_input_blur>
|
|
<InputSuffix slot>
|
|
<Icon icon=icondata::AiCalendarOutlined style="font-size: 18px"/>
|
|
</InputSuffix>
|
|
</Input>
|
|
</div>
|
|
<Follower slot show=is_show_panel placement=FollowerPlacement::BottomStart>
|
|
<Panel
|
|
date_picker_ref
|
|
close_panel
|
|
selected_date=panel_selected_date
|
|
comp_ref=panel_ref
|
|
/>
|
|
</Follower>
|
|
</Binder>
|
|
}
|
|
}
|