mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34:15 -05:00
Feat/time library (#42)
* feat: change the time library to chrono * fix: calendar demo
This commit is contained in:
parent
c0f45c4325
commit
a61e687d7e
4 changed files with 71 additions and 68 deletions
|
@ -38,7 +38,7 @@ icondata = { version = "0.1.0", features = [
|
|||
icondata_core = "0.0.2"
|
||||
uuid = { version = "1.5.0", features = ["v4"] }
|
||||
cfg-if = "1.0.0"
|
||||
time = { version = "0.3.30", features = ["wasm-bindgen"] }
|
||||
chrono = "0.4.31"
|
||||
|
||||
[features]
|
||||
default = ["csr"]
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
use crate::components::{Demo, DemoCode};
|
||||
use leptos::*;
|
||||
use prisms::highlight_str;
|
||||
use thaw::chrono::prelude::*;
|
||||
use thaw::*;
|
||||
|
||||
#[component]
|
||||
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! {
|
||||
<div style="width: 896px; margin: 0 auto;">
|
||||
<h1>"Calendar"</h1>
|
||||
<Demo>
|
||||
<Calendar value />
|
||||
<Calendar value/>
|
||||
<DemoCode slot>
|
||||
|
||||
{highlight_str!(
|
||||
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! {
|
||||
<Calendar value />
|
||||
|
@ -39,8 +42,12 @@ pub fn CalendarPage() -> impl IntoView {
|
|||
<tbody>
|
||||
<tr>
|
||||
<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>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
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 leptos::*;
|
||||
use std::ops::Deref;
|
||||
pub use theme::CalendarTheme;
|
||||
pub use time::Date;
|
||||
use time::Month;
|
||||
pub use time::OffsetDateTime;
|
||||
|
||||
#[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"));
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
|
@ -35,14 +38,15 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
|
|||
});
|
||||
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 |_| {
|
||||
let selected_date = value.get();
|
||||
let show_date_data = show_date.get_untracked();
|
||||
if selected_date.year() != show_date_data.year()
|
||||
|| selected_date.month() != show_date_data.month()
|
||||
{
|
||||
show_date.set(selected_date);
|
||||
if let Some(selected_date) = value.get() {
|
||||
let show_date_data = show_date.get_untracked();
|
||||
if selected_date.year() != show_date_data.year()
|
||||
|| selected_date.month() != show_date_data.month()
|
||||
{
|
||||
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 current_date = show_date;
|
||||
let mut current_weekday_number = None::<u8>;
|
||||
let mut current_weekday_number = None::<u32>;
|
||||
loop {
|
||||
let Some(date) = current_date.previous_day() else {
|
||||
break;
|
||||
};
|
||||
let date = current_date - Days::new(1);
|
||||
if date.month() != show_date_month {
|
||||
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();
|
||||
if weekday_number == 0 {
|
||||
|
@ -78,12 +80,10 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
|
|||
current_date = show_date;
|
||||
current_weekday_number = None;
|
||||
loop {
|
||||
let Some(date) = current_date.next_day() else {
|
||||
break;
|
||||
};
|
||||
let date = current_date + Days::new(1);
|
||||
if date.month() != show_date_month {
|
||||
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();
|
||||
if weekday_number == 6 {
|
||||
|
@ -101,15 +101,15 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
|
|||
|
||||
let previous_month = move |_| {
|
||||
show_date.update(|date| {
|
||||
*date = date.previous_month();
|
||||
*date = *date - Months::new(1);
|
||||
});
|
||||
};
|
||||
let today = move |_| {
|
||||
show_date.set(OffsetDateTime::now_utc().date());
|
||||
show_date.set(Local::now().date_naive());
|
||||
};
|
||||
let next_month = move |_| {
|
||||
show_date.update(|date| {
|
||||
*date = date.next_month();
|
||||
*date = *date + Months::new(1);
|
||||
});
|
||||
};
|
||||
view! {
|
||||
|
@ -118,19 +118,32 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
|
|||
<span class="thaw-calendar__header-title">
|
||||
|
||||
{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>
|
||||
<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>
|
||||
"Today"
|
||||
</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>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -153,19 +166,20 @@ pub fn Calendar(#[prop(into)] value: RwSignal<Date>) -> impl IntoView {
|
|||
}
|
||||
|
||||
#[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 date = date.clone();
|
||||
move |_| {
|
||||
let value_date = value.get();
|
||||
value_date.to_calendar_date() == date.to_calendar_date()
|
||||
}
|
||||
move |_| value.with(|value_date| value_date.as_ref() == Some(date.deref()))
|
||||
});
|
||||
let weekday_str = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
let on_click = {
|
||||
let date = date.clone();
|
||||
move |_| {
|
||||
value.set(date.deref().clone());
|
||||
value.set(Some(date.deref().clone()));
|
||||
}
|
||||
};
|
||||
view! {
|
||||
|
@ -196,9 +210,9 @@ fn CalendarItem(value: RwSignal<Date>, index: usize, date: CalendarItemDate) ->
|
|||
|
||||
#[derive(Clone, PartialEq)]
|
||||
enum CalendarItemDate {
|
||||
Previous(Date),
|
||||
Current(Date),
|
||||
Next(Date),
|
||||
Previous(NaiveDate),
|
||||
Current(NaiveDate),
|
||||
Next(NaiveDate),
|
||||
}
|
||||
|
||||
impl CalendarItemDate {
|
||||
|
@ -211,13 +225,13 @@ impl CalendarItemDate {
|
|||
|
||||
fn is_today(&self) -> bool {
|
||||
let date = self.deref();
|
||||
let now_date = OffsetDateTime::now_utc().date();
|
||||
now_date.to_calendar_date() == date.to_calendar_date()
|
||||
let now_date = now_date();
|
||||
&now_date == date
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for CalendarItemDate {
|
||||
type Target = Date;
|
||||
type Target = NaiveDate;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
|
@ -228,25 +242,6 @@ impl Deref for CalendarItemDate {
|
|||
}
|
||||
}
|
||||
|
||||
trait DateMonth {
|
||||
fn previous_month(&self) -> Self;
|
||||
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()
|
||||
}
|
||||
fn now_date() -> NaiveDate {
|
||||
Local::now().date_naive()
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ pub use button::*;
|
|||
pub use calendar::*;
|
||||
pub use card::*;
|
||||
pub use checkbox::*;
|
||||
pub use chrono;
|
||||
pub use code::*;
|
||||
pub use color_picker::*;
|
||||
pub use divider::*;
|
||||
|
|
Loading…
Add table
Reference in a new issue