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"
|
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"]
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
Loading…
Add table
Reference in a new issue