Feat/time library (#42)

* feat: change the time library to chrono

* fix: calendar demo
This commit is contained in:
luoxiaozero 2023-12-10 03:22:37 +08:00 committed by GitHub
parent c0f45c4325
commit a61e687d7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 68 deletions

View file

@ -38,7 +38,7 @@ icondata = { version = "0.1.0", features = [
icondata_core = "0.0.2" icondata_core = "0.0.2"
uuid = { version = "1.5.0", features = ["v4"] } uuid = { version = "1.5.0", features = ["v4"] }
cfg-if = "1.0.0" cfg-if = "1.0.0"
time = { version = "0.3.30", features = ["wasm-bindgen"] } chrono = "0.4.31"
[features] [features]
default = ["csr"] default = ["csr"]

View file

@ -1,21 +1,24 @@
use crate::components::{Demo, DemoCode}; use crate::components::{Demo, DemoCode};
use leptos::*; use leptos::*;
use prisms::highlight_str; use prisms::highlight_str;
use thaw::chrono::prelude::*;
use thaw::*; use thaw::*;
#[component] #[component]
pub fn CalendarPage() -> impl IntoView { pub fn CalendarPage() -> impl IntoView {
let value = create_rw_signal(OffsetDateTime::now_utc().date()); let value = create_rw_signal(Some(Local::now().date_naive()));
view! { view! {
<div style="width: 896px; margin: 0 auto;"> <div style="width: 896px; margin: 0 auto;">
<h1>"Calendar"</h1> <h1>"Calendar"</h1>
<Demo> <Demo>
<Calendar value /> <Calendar value/>
<DemoCode slot> <DemoCode slot>
{highlight_str!( {highlight_str!(
r#" r#"
let value = create_rw_singal(OffsetDateTime::now_utc().date()); use thaw::chrono::prelude::*;
let value = create_rw_signal(Some(Local::now().date_naive()));
view! { view! {
<Calendar value /> <Calendar value />
@ -39,8 +42,12 @@ pub fn CalendarPage() -> impl IntoView {
<tbody> <tbody>
<tr> <tr>
<td>"value"</td> <td>"value"</td>
<td>"RwSignal<Date>"</td> <td>
<td></td> <Text code=true>"RwSignal<Option<NaiveDate>>"</Text>
</td>
<td>
<Text code=true>"Default::deafult()"</Text>
</td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>

View file

@ -1,16 +1,19 @@
mod theme; mod theme;
use crate::{use_theme, utils::mount_style, Button, ButtonGroup, ButtonVariant, Theme}; use crate::{
chrono::{Datelike, Days, Local, NaiveDate},
use_theme,
utils::mount_style,
Button, ButtonGroup, ButtonVariant, Theme,
};
use chrono::{Month, Months};
use icondata::AiIcon; use icondata::AiIcon;
use leptos::*; use leptos::*;
use std::ops::Deref; use std::ops::Deref;
pub use theme::CalendarTheme; pub use theme::CalendarTheme;
pub use time::Date;
use time::Month;
pub use time::OffsetDateTime;
#[component] #[component]
pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView { pub fn Calendar(#[prop(optional, into)] value: RwSignal<Option<NaiveDate>>) -> impl IntoView {
mount_style("calendar", include_str!("./calendar.css")); mount_style("calendar", include_str!("./calendar.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
@ -35,14 +38,15 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
}); });
css_vars css_vars
}); });
let show_date = create_rw_signal(value.get_untracked()); let show_date = create_rw_signal(value.get_untracked().unwrap_or(now_date()));
create_effect(move |_| { create_effect(move |_| {
let selected_date = value.get(); if let Some(selected_date) = value.get() {
let show_date_data = show_date.get_untracked(); let show_date_data = show_date.get_untracked();
if selected_date.year() != show_date_data.year() if selected_date.year() != show_date_data.year()
|| selected_date.month() != show_date_data.month() || selected_date.month() != show_date_data.month()
{ {
show_date.set(selected_date); show_date.set(selected_date);
}
} }
}); });
@ -52,14 +56,12 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
let mut dates = vec![]; let mut dates = vec![];
let mut current_date = show_date; let mut current_date = show_date;
let mut current_weekday_number = None::<u8>; let mut current_weekday_number = None::<u32>;
loop { loop {
let Some(date) = current_date.previous_day() else { let date = current_date - Days::new(1);
break;
};
if date.month() != show_date_month { if date.month() != show_date_month {
if current_weekday_number.is_none() { if current_weekday_number.is_none() {
current_weekday_number = Some(current_date.weekday().number_days_from_sunday()); current_weekday_number = Some(current_date.weekday().num_days_from_sunday());
} }
let weekday_number = current_weekday_number.unwrap(); let weekday_number = current_weekday_number.unwrap();
if weekday_number == 0 { if weekday_number == 0 {
@ -78,12 +80,10 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
current_date = show_date; current_date = show_date;
current_weekday_number = None; current_weekday_number = None;
loop { loop {
let Some(date) = current_date.next_day() else { let date = current_date + Days::new(1);
break;
};
if date.month() != show_date_month { if date.month() != show_date_month {
if current_weekday_number.is_none() { if current_weekday_number.is_none() {
current_weekday_number = Some(current_date.weekday().number_days_from_sunday()); current_weekday_number = Some(current_date.weekday().num_days_from_sunday());
} }
let weekday_number = current_weekday_number.unwrap(); let weekday_number = current_weekday_number.unwrap();
if weekday_number == 6 { if weekday_number == 6 {
@ -101,15 +101,15 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
let previous_month = move |_| { let previous_month = move |_| {
show_date.update(|date| { show_date.update(|date| {
*date = date.previous_month(); *date = *date - Months::new(1);
}); });
}; };
let today = move |_| { let today = move |_| {
show_date.set(OffsetDateTime::now_utc().date()); show_date.set(Local::now().date_naive());
}; };
let next_month = move |_| { let next_month = move |_| {
show_date.update(|date| { show_date.update(|date| {
*date = date.next_month(); *date = *date + Months::new(1);
}); });
}; };
view! { view! {
@ -118,19 +118,32 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
<span class="thaw-calendar__header-title"> <span class="thaw-calendar__header-title">
{move || { {move || {
show_date.with(|date| { format!("{} {}", date.month(), date.year()) }) show_date
.with(|date| {
format!(
"{} {}",
Month::try_from(date.month() as u8).unwrap().name(),
date.year(),
)
})
}} }}
</span> </span>
<span> <span>
<ButtonGroup> <ButtonGroup>
<Button variant=ButtonVariant::Solid icon=AiIcon::AiLeftOutlined on_click=previous_month> <Button
</Button> variant=ButtonVariant::Solid
icon=AiIcon::AiLeftOutlined
on_click=previous_month
/>
<Button variant=ButtonVariant::Solid on_click=today> <Button variant=ButtonVariant::Solid on_click=today>
"Today" "Today"
</Button> </Button>
<Button variant=ButtonVariant::Solid icon=AiIcon::AiRightOutlined on_click=next_month> <Button
</Button> variant=ButtonVariant::Solid
icon=AiIcon::AiRightOutlined
on_click=next_month
/>
</ButtonGroup> </ButtonGroup>
</span> </span>
</div> </div>
@ -153,19 +166,20 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
} }
#[component] #[component]
fn CalendarItem(value: RwSignal<Date>, index: usize, date: CalendarItemDate) -> impl IntoView { fn CalendarItem(
value: RwSignal<Option<NaiveDate>>,
index: usize,
date: CalendarItemDate,
) -> impl IntoView {
let is_selected = create_memo({ let is_selected = create_memo({
let date = date.clone(); let date = date.clone();
move |_| { move |_| value.with(|value_date| value_date.as_ref() == Some(date.deref()))
let value_date = value.get();
value_date.to_calendar_date() == date.to_calendar_date()
}
}); });
let weekday_str = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; let weekday_str = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let on_click = { let on_click = {
let date = date.clone(); let date = date.clone();
move |_| { move |_| {
value.set(date.deref().clone()); value.set(Some(date.deref().clone()));
} }
}; };
view! { view! {
@ -196,9 +210,9 @@ fn CalendarItem(value: RwSignal<Date>, index: usize, date: CalendarItemDate) ->
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
enum CalendarItemDate { enum CalendarItemDate {
Previous(Date), Previous(NaiveDate),
Current(Date), Current(NaiveDate),
Next(Date), Next(NaiveDate),
} }
impl CalendarItemDate { impl CalendarItemDate {
@ -211,13 +225,13 @@ impl CalendarItemDate {
fn is_today(&self) -> bool { fn is_today(&self) -> bool {
let date = self.deref(); let date = self.deref();
let now_date = OffsetDateTime::now_utc().date(); let now_date = now_date();
now_date.to_calendar_date() == date.to_calendar_date() &now_date == date
} }
} }
impl Deref for CalendarItemDate { impl Deref for CalendarItemDate {
type Target = Date; type Target = NaiveDate;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
match self { match self {
@ -228,25 +242,6 @@ impl Deref for CalendarItemDate {
} }
} }
trait DateMonth { fn now_date() -> NaiveDate {
fn previous_month(&self) -> Self; Local::now().date_naive()
fn next_month(&self) -> Self;
}
impl DateMonth for Date {
fn previous_month(&self) -> Self {
let mut year = self.year();
if self.month() == Month::January {
year -= 1
}
Date::from_calendar_date(year, self.month().previous(), 1).unwrap()
}
fn next_month(&self) -> Self {
let mut year = self.year();
if self.month() == Month::December {
year += 1
}
Date::from_calendar_date(year, self.month().next(), 1).unwrap()
}
} }

View file

@ -47,6 +47,7 @@ pub use button::*;
pub use calendar::*; pub use calendar::*;
pub use card::*; pub use card::*;
pub use checkbox::*; pub use checkbox::*;
pub use chrono;
pub use code::*; pub use code::*;
pub use color_picker::*; pub use color_picker::*;
pub use divider::*; pub use divider::*;