feat: Calendar adds children prop (#239)

This commit is contained in:
luoxiaozero 2024-08-24 01:36:12 +08:00 committed by GitHub
parent 97212d7fda
commit b476835c11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 7 deletions

View file

@ -8,14 +8,17 @@ let option_value = RwSignal::new(Some(Local::now().date_naive()));
view! { view! {
<Space vertical=true> <Space vertical=true>
<Calendar value /> <Calendar value />
<Calendar value=option_value /> <Calendar value=option_value let(date: &NaiveDate)>
{date.year()}"-"{date.month()}"-"{date.day()}
</Calendar>
</Space> </Space>
} }
``` ```
### Calendar Props ### Calendar Props
| Name | Type | Default | Desciption | | Name | Type | Default | Desciption |
| ----- | ------------------------ | -------------------- | -------------- | | -------- | ----------------------------- | -------------------- | -------------- |
| class | `MaybeProp<String>` | `Default::default()` | | | class | `MaybeProp<String>` | `Default::default()` | |
| value | `OptionModel<NaiveDate>` | `Default::default()` | selected date. | | value | `OptionModel<NaiveDate>` | `Default::default()` | selected date. |
| children | `Option<CalendarChildrenFn>>` | `None` | . |

View file

@ -1,7 +1,8 @@
use crate::{Button, ButtonGroup}; use crate::{Button, ButtonGroup};
use chrono::{Datelike, Days, Local, Month, Months, NaiveDate}; use chrono::{Datelike, Days, Local, Month, Months, NaiveDate};
use leptos::prelude::*; use leptos::prelude::*;
use std::ops::Deref; use std::{ops::Deref, sync::Arc};
use tachys::view::any_view::AnyView;
use thaw_utils::{class_list, mount_style, OptionModel, OptionModelWithValue}; use thaw_utils::{class_list, mount_style, OptionModel, OptionModelWithValue};
#[component] #[component]
@ -10,6 +11,7 @@ pub fn Calendar(
/// selected date. /// selected date.
#[prop(optional, into)] #[prop(optional, into)]
value: OptionModel<NaiveDate>, value: OptionModel<NaiveDate>,
#[prop(optional, into)] children: Option<CalendarChildrenFn>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("calendar", include_str!("./calendar.css")); mount_style("calendar", include_str!("./calendar.css"));
let show_date = RwSignal::new(value.get_untracked().unwrap_or(now_date())); let show_date = RwSignal::new(value.get_untracked().unwrap_or(now_date()));
@ -118,7 +120,14 @@ pub fn Calendar(
.into_iter() .into_iter()
.enumerate() .enumerate()
.map(|(index, date)| { .map(|(index, date)| {
view! { <CalendarItem value index=index date=date /> } view! {
<CalendarItem
value
index=index
date=date
children=children.clone()
/>
}
}) })
.collect_view() .collect_view()
}} }}
@ -133,6 +142,7 @@ fn CalendarItem(
value: OptionModel<NaiveDate>, value: OptionModel<NaiveDate>,
index: usize, index: usize,
date: CalendarItemDate, date: CalendarItemDate,
children: Option<CalendarChildrenFn>,
) -> impl IntoView { ) -> impl IntoView {
let is_selected = Memo::new({ let is_selected = Memo::new({
let date = date.clone(); let date = date.clone();
@ -171,6 +181,7 @@ fn CalendarItem(
}} }}
</div> </div>
{children.map(|c| c(date.deref()))}
<div class="thaw-calendar-item__bar"></div> <div class="thaw-calendar-item__bar"></div>
</div> </div>
} }
@ -213,3 +224,24 @@ impl Deref for CalendarItemDate {
pub(crate) fn now_date() -> NaiveDate { pub(crate) fn now_date() -> NaiveDate {
Local::now().date_naive() Local::now().date_naive()
} }
#[derive(Clone)]
pub struct CalendarChildrenFn(Arc<dyn Fn(&NaiveDate) -> AnyView<Dom> + Send + Sync>);
impl Deref for CalendarChildrenFn {
type Target = Arc<dyn Fn(&NaiveDate) -> AnyView<Dom> + Send + Sync>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<F, C> From<F> for CalendarChildrenFn
where
F: Fn(&NaiveDate) -> C + Send + Sync + 'static,
C: RenderHtml<Dom> + Send + 'static,
{
fn from(f: F) -> Self {
Self(Arc::new(move |date| f(date).into_any()))
}
}