Rewrite some components to use render method
This commit is contained in:
parent
682066b561
commit
2d7ce5762a
@ -48,8 +48,8 @@ impl<'l> Default for ChildBuilder<'l> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l> ToNode for ChildBuilder<'l> {
|
impl<'l> ChildBuilder<'l> {
|
||||||
fn into_node(self) -> Node<Msg> {
|
pub fn render(self) -> Node<Msg> {
|
||||||
let ChildBuilder {
|
let ChildBuilder {
|
||||||
field_id,
|
field_id,
|
||||||
name,
|
name,
|
||||||
@ -60,10 +60,10 @@ impl<'l> ToNode for ChildBuilder<'l> {
|
|||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let id = field_id.to_string();
|
let id = field_id.to_string();
|
||||||
let field_id_clone = field_id.clone();
|
let handler: EventHandler<Msg> = {
|
||||||
let handler: EventHandler<Msg> = mouse_ev(Ev::Click, move |_| {
|
let id = field_id.clone();
|
||||||
Msg::U32InputChanged(field_id_clone, value)
|
mouse_ev(Ev::Click, move |_| Msg::U32InputChanged(id, value))
|
||||||
});
|
};
|
||||||
|
|
||||||
div![
|
div![
|
||||||
C![
|
C![
|
||||||
@ -81,7 +81,7 @@ impl<'l> ToNode for ChildBuilder<'l> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct StyledCheckbox<'l, Options>
|
pub struct StyledCheckbox<'l, Options>
|
||||||
where
|
where
|
||||||
Options: Iterator<Item = ChildBuilder<'l>>,
|
Options: Iterator<Item = ChildBuilder<'l>>,
|
||||||
@ -90,15 +90,23 @@ where
|
|||||||
pub class_list: &'l str,
|
pub class_list: &'l str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l, Options> Default for StyledCheckbox<'l, Options>
|
impl<'l, Options> StyledCheckbox<'l, Options>
|
||||||
where
|
where
|
||||||
Options: Iterator<Item = ChildBuilder<'l>>,
|
Options: Iterator<Item = ChildBuilder<'l>>,
|
||||||
{
|
{
|
||||||
fn default() -> Self {
|
pub fn render(self) -> Node<Msg> {
|
||||||
Self {
|
let StyledCheckbox {
|
||||||
options: None,
|
options,
|
||||||
class_list: "",
|
class_list,
|
||||||
}
|
} = self;
|
||||||
|
|
||||||
|
div![
|
||||||
|
C!["styledCheckbox", class_list],
|
||||||
|
options.map_or_else(
|
||||||
|
|| vec![Node::Empty],
|
||||||
|
|v| v.map(ChildBuilder::render).collect(),
|
||||||
|
)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,23 +115,6 @@ where
|
|||||||
Options: Iterator<Item = ChildBuilder<'l>>,
|
Options: Iterator<Item = ChildBuilder<'l>>,
|
||||||
{
|
{
|
||||||
fn into_node(self) -> Node<Msg> {
|
fn into_node(self) -> Node<Msg> {
|
||||||
render(self)
|
self.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render<'l, Options>(values: StyledCheckbox<'l, Options>) -> Node<Msg>
|
|
||||||
where
|
|
||||||
Options: Iterator<Item = ChildBuilder<'l>>,
|
|
||||||
{
|
|
||||||
let StyledCheckbox {
|
|
||||||
options,
|
|
||||||
class_list,
|
|
||||||
} = values;
|
|
||||||
|
|
||||||
let opt: Vec<Node<Msg>> = match options {
|
|
||||||
Some(options) => options.map(|child| child.into_node()).collect(),
|
|
||||||
_ => vec![Node::Empty],
|
|
||||||
};
|
|
||||||
|
|
||||||
div![C!["styledCheckbox", class_list], opt,]
|
|
||||||
}
|
|
||||||
|
@ -20,6 +20,53 @@ pub struct StyledConfirmModal<'l> {
|
|||||||
pub on_confirm: Option<EventHandler<Msg>>,
|
pub on_confirm: Option<EventHandler<Msg>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'l> StyledConfirmModal<'l> {
|
||||||
|
pub fn render(self) -> Node<Msg> {
|
||||||
|
let StyledConfirmModal {
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
confirm_text,
|
||||||
|
cancel_text,
|
||||||
|
on_confirm,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let title = if title.is_empty() { TITLE } else { title };
|
||||||
|
let message = if message.is_empty() { MESSAGE } else { message };
|
||||||
|
|
||||||
|
let confirm_button = StyledButton {
|
||||||
|
text: Some(match confirm_text {
|
||||||
|
s if s.is_empty() => CONFIRM_TEXT,
|
||||||
|
_ => confirm_text,
|
||||||
|
}),
|
||||||
|
on_click: on_confirm,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.render();
|
||||||
|
let cancel_button = StyledButton {
|
||||||
|
text: Some(match cancel_text {
|
||||||
|
s if s.is_empty() => CANCEL_TEXT,
|
||||||
|
_ => cancel_text,
|
||||||
|
}),
|
||||||
|
variant: ButtonVariant::Secondary,
|
||||||
|
on_click: Some(mouse_ev(Ev::Click, |_| Msg::ModalDropped)),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.render();
|
||||||
|
|
||||||
|
StyledModal {
|
||||||
|
width: Some(600),
|
||||||
|
children: vec![
|
||||||
|
div![C!["title"], title],
|
||||||
|
p![C!["message"], message],
|
||||||
|
div![C!["actions"], confirm_button, cancel_button],
|
||||||
|
],
|
||||||
|
class_list: "confirmModal",
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.into_node()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'l> Default for StyledConfirmModal<'l> {
|
impl<'l> Default for StyledConfirmModal<'l> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -34,60 +81,6 @@ impl<'l> Default for StyledConfirmModal<'l> {
|
|||||||
|
|
||||||
impl<'l> ToNode for StyledConfirmModal<'l> {
|
impl<'l> ToNode for StyledConfirmModal<'l> {
|
||||||
fn into_node(self) -> Node<Msg> {
|
fn into_node(self) -> Node<Msg> {
|
||||||
render(self)
|
self.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(values: StyledConfirmModal) -> Node<Msg> {
|
|
||||||
let StyledConfirmModal {
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
confirm_text,
|
|
||||||
cancel_text,
|
|
||||||
on_confirm,
|
|
||||||
} = values;
|
|
||||||
|
|
||||||
let title = if title.is_empty() { TITLE } else { title };
|
|
||||||
let message = if message.is_empty() { MESSAGE } else { message };
|
|
||||||
let confirm_text = if confirm_text.is_empty() {
|
|
||||||
CONFIRM_TEXT
|
|
||||||
} else {
|
|
||||||
confirm_text
|
|
||||||
};
|
|
||||||
let cancel_text = if cancel_text.is_empty() {
|
|
||||||
CANCEL_TEXT
|
|
||||||
} else {
|
|
||||||
cancel_text
|
|
||||||
};
|
|
||||||
|
|
||||||
let message_node = match message {
|
|
||||||
_ if message.is_empty() => empty![],
|
|
||||||
_ => p![C!["message"], message],
|
|
||||||
};
|
|
||||||
|
|
||||||
let confirm_button = StyledButton {
|
|
||||||
text: Some(confirm_text),
|
|
||||||
on_click: on_confirm,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node();
|
|
||||||
let cancel_button = StyledButton {
|
|
||||||
text: Some(cancel_text),
|
|
||||||
variant: ButtonVariant::Secondary,
|
|
||||||
on_click: Some(mouse_ev(Ev::Click, |_| Msg::ModalDropped)),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node();
|
|
||||||
|
|
||||||
StyledModal {
|
|
||||||
width: Some(600),
|
|
||||||
children: vec![
|
|
||||||
div![C!["title"], title],
|
|
||||||
message_node,
|
|
||||||
div![C!["actions"], confirm_button, cancel_button],
|
|
||||||
],
|
|
||||||
class_list: "confirmModal",
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node()
|
|
||||||
}
|
|
||||||
|
@ -75,208 +75,231 @@ pub struct StyledDateTimeInput {
|
|||||||
pub popup_visible: bool,
|
pub popup_visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StyledDateTimeInput {
|
||||||
|
pub fn render(self) -> Node<Msg> {
|
||||||
|
let timestamp = self
|
||||||
|
.timestamp
|
||||||
|
.unwrap_or_else(|| chrono::Utc::now().naive_utc());
|
||||||
|
let start = timestamp.with_day0(0).unwrap();
|
||||||
|
let end = (start + Duration::days(32)).with_day0(0).unwrap();
|
||||||
|
|
||||||
|
let calendar_start = StyledDateTimeInput::calendar_start(start.clone());
|
||||||
|
let calendar_end = StyledDateTimeInput::calendar_end(end.clone());
|
||||||
|
let current_month_range = start..=end;
|
||||||
|
let mut current = calendar_start;
|
||||||
|
let mut weeks = vec![];
|
||||||
|
let range = calendar_start..=calendar_end;
|
||||||
|
let mut current_week = vec![];
|
||||||
|
loop {
|
||||||
|
if !range.contains(¤t) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if current.weekday() == Weekday::Mon && !current_week.is_empty() {
|
||||||
|
weeks.push(div![C!["week"], current_week]);
|
||||||
|
current_week = vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
current_week.push(
|
||||||
|
DayCell {
|
||||||
|
field_id: &self.field_id,
|
||||||
|
timestamp: ×tamp,
|
||||||
|
current: ¤t,
|
||||||
|
current_month_range: ¤t_month_range,
|
||||||
|
}
|
||||||
|
.render(),
|
||||||
|
);
|
||||||
|
|
||||||
|
current += Duration::days(1);
|
||||||
|
}
|
||||||
|
if !current_week.is_empty() {
|
||||||
|
weeks.push(div![C!["week"], current_week]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let left_action = {
|
||||||
|
let field_id = self.field_id.clone();
|
||||||
|
let current = timestamp;
|
||||||
|
let on_click_left = mouse_ev(Ev::Click, move |ev| {
|
||||||
|
ev.stop_propagation();
|
||||||
|
ev.prevent_default();
|
||||||
|
let last_day_of_prev_month = current.with_day0(0).unwrap() - Duration::days(1);
|
||||||
|
|
||||||
|
let date = last_day_of_prev_month
|
||||||
|
.with_day0(timestamp.day0())
|
||||||
|
.unwrap_or(last_day_of_prev_month);
|
||||||
|
Msg::StyledDateTimeInputChanged(
|
||||||
|
field_id,
|
||||||
|
StyledDateTimeChanged::MonthChanged(Some(date)),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
StyledButton {
|
||||||
|
on_click: Some(on_click_left),
|
||||||
|
icon: Some(Icon::DoubleLeft.into_node()),
|
||||||
|
variant: ButtonVariant::Empty,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.into_node()
|
||||||
|
};
|
||||||
|
let right_action = {
|
||||||
|
let field_id = self.field_id.clone();
|
||||||
|
let current = timestamp;
|
||||||
|
let on_click_right = mouse_ev(Ev::Click, move |ev| {
|
||||||
|
ev.stop_propagation();
|
||||||
|
ev.prevent_default();
|
||||||
|
let first_day_of_next_month = (current + Duration::days(32)).with_day0(0).unwrap();
|
||||||
|
let last_day_of_next_month = (first_day_of_next_month + Duration::days(32))
|
||||||
|
.with_day0(0)
|
||||||
|
.unwrap()
|
||||||
|
- Duration::days(1);
|
||||||
|
let date = first_day_of_next_month
|
||||||
|
.with_day0(timestamp.day0())
|
||||||
|
.unwrap_or(last_day_of_next_month);
|
||||||
|
Msg::StyledDateTimeInputChanged(
|
||||||
|
field_id,
|
||||||
|
StyledDateTimeChanged::MonthChanged(Some(date)),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
StyledButton {
|
||||||
|
on_click: Some(on_click_right),
|
||||||
|
icon: Some(Icon::DoubleRight.into_node()),
|
||||||
|
variant: ButtonVariant::Empty,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
};
|
||||||
|
|
||||||
|
let tooltip = StyledTooltip {
|
||||||
|
visible: self.popup_visible,
|
||||||
|
class_list: "",
|
||||||
|
children: vec![
|
||||||
|
h2![
|
||||||
|
left_action,
|
||||||
|
span![current.format("%B %Y").to_string()],
|
||||||
|
right_action
|
||||||
|
],
|
||||||
|
div![
|
||||||
|
C!["calendar"],
|
||||||
|
div![
|
||||||
|
C!["weekHeader week"],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Mon).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Tue).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Wed).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Thu).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Fri).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Sat).as_str()],
|
||||||
|
div![C!["day"], format!("{}", Weekday::Sun).as_str()],
|
||||||
|
],
|
||||||
|
weeks
|
||||||
|
],
|
||||||
|
],
|
||||||
|
variant: TooltipVariant::DateTimeBuilder,
|
||||||
|
}
|
||||||
|
.render();
|
||||||
|
|
||||||
|
let input = {
|
||||||
|
let field_id = self.field_id.clone();
|
||||||
|
let visible = self.popup_visible;
|
||||||
|
let on_focus = ev(Ev::Click, move |ev| {
|
||||||
|
ev.prevent_default();
|
||||||
|
ev.stop_propagation();
|
||||||
|
Msg::StyledDateTimeInputChanged(
|
||||||
|
field_id,
|
||||||
|
StyledDateTimeChanged::PopupVisibilityChanged(!visible),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let text = self
|
||||||
|
.timestamp
|
||||||
|
.unwrap_or_else(|| Utc::now().naive_utc())
|
||||||
|
.date()
|
||||||
|
.format("%d/%m/%Y")
|
||||||
|
.to_string();
|
||||||
|
StyledButton {
|
||||||
|
on_click: Some(on_focus),
|
||||||
|
text: Some(text.as_str()),
|
||||||
|
variant: ButtonVariant::Empty,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
};
|
||||||
|
|
||||||
|
div![
|
||||||
|
C!["styledDateTimeInput", format!("{}", self.field_id)],
|
||||||
|
input,
|
||||||
|
tooltip,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn calendar_start(start: NaiveDateTime) -> NaiveDateTime {
|
||||||
|
match start.weekday() {
|
||||||
|
Weekday::Mon => start,
|
||||||
|
Weekday::Tue => start - Duration::days(1),
|
||||||
|
Weekday::Wed => start - Duration::days(2),
|
||||||
|
Weekday::Thu => start - Duration::days(3),
|
||||||
|
Weekday::Fri => start - Duration::days(4),
|
||||||
|
Weekday::Sat => start - Duration::days(5),
|
||||||
|
Weekday::Sun => start - Duration::days(6),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn calendar_end(end: NaiveDateTime) -> NaiveDateTime {
|
||||||
|
match end.weekday() {
|
||||||
|
Weekday::Mon => end + Duration::days(6),
|
||||||
|
Weekday::Tue => end + Duration::days(5),
|
||||||
|
Weekday::Wed => end + Duration::days(4),
|
||||||
|
Weekday::Thu => end + Duration::days(3),
|
||||||
|
Weekday::Fri => end + Duration::days(2),
|
||||||
|
Weekday::Sat => end + Duration::days(1),
|
||||||
|
Weekday::Sun => end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToNode for StyledDateTimeInput {
|
impl ToNode for StyledDateTimeInput {
|
||||||
fn into_node(self) -> Node<Msg> {
|
fn into_node(self) -> Node<Msg> {
|
||||||
render(self)
|
self.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(values: StyledDateTimeInput) -> Node<Msg> {
|
pub struct DayCell<'l> {
|
||||||
let timestamp = values
|
field_id: &'l FieldId,
|
||||||
.timestamp
|
timestamp: &'l NaiveDateTime,
|
||||||
.unwrap_or_else(|| chrono::Utc::now().naive_utc());
|
current: &'l NaiveDateTime,
|
||||||
let start = timestamp.with_day0(0).unwrap();
|
current_month_range: &'l RangeInclusive<NaiveDateTime>,
|
||||||
let end = (start + Duration::days(32)).with_day0(0).unwrap();
|
}
|
||||||
|
|
||||||
let calendar_start = match start.weekday() {
|
impl<'l> DayCell<'l> {
|
||||||
Weekday::Mon => start,
|
pub fn render(self) -> Node<Msg> {
|
||||||
Weekday::Tue => start - Duration::days(1),
|
let on_click = {
|
||||||
Weekday::Wed => start - Duration::days(2),
|
let field_id = self.field_id.clone();
|
||||||
Weekday::Thu => start - Duration::days(3),
|
let date = *self.current;
|
||||||
Weekday::Fri => start - Duration::days(4),
|
ev(Ev::Click, move |ev| {
|
||||||
Weekday::Sat => start - Duration::days(5),
|
ev.stop_propagation();
|
||||||
Weekday::Sun => start - Duration::days(6),
|
ev.prevent_default();
|
||||||
};
|
Msg::StyledDateTimeInputChanged(
|
||||||
let calendar_end = match end.weekday() {
|
field_id,
|
||||||
Weekday::Mon => end + Duration::days(6),
|
StyledDateTimeChanged::DayChanged(Some(date)),
|
||||||
Weekday::Tue => end + Duration::days(5),
|
)
|
||||||
Weekday::Wed => end + Duration::days(4),
|
})
|
||||||
Weekday::Thu => end + Duration::days(3),
|
};
|
||||||
Weekday::Fri => end + Duration::days(2),
|
div![
|
||||||
Weekday::Sat => end + Duration::days(1),
|
C![
|
||||||
Weekday::Sun => end,
|
"day",
|
||||||
};
|
format!("{}", self.current.weekday()),
|
||||||
let current_month_range = start..=end;
|
IF![self.is_selected() => "selected"],
|
||||||
let mut current = calendar_start;
|
if self.current_month_range.contains(&self.current) {
|
||||||
let mut weeks = vec![];
|
"inCurrentMonth"
|
||||||
let range = calendar_start..=calendar_end;
|
} else {
|
||||||
let mut current_week = vec![];
|
"outCurrentMonth"
|
||||||
loop {
|
},
|
||||||
if !range.contains(¤t) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if current.weekday() == Weekday::Mon && !current_week.is_empty() {
|
|
||||||
weeks.push(div![C!["week"], current_week]);
|
|
||||||
current_week = vec![];
|
|
||||||
}
|
|
||||||
|
|
||||||
current_week.push(day_cell(
|
|
||||||
&values.field_id,
|
|
||||||
×tamp,
|
|
||||||
¤t,
|
|
||||||
¤t_month_range,
|
|
||||||
));
|
|
||||||
|
|
||||||
current += Duration::days(1);
|
|
||||||
}
|
|
||||||
if !current_week.is_empty() {
|
|
||||||
weeks.push(div![C!["week"], current_week]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let left_action = {
|
|
||||||
let field_id = values.field_id.clone();
|
|
||||||
let current = timestamp;
|
|
||||||
let on_click_left = mouse_ev(Ev::Click, move |ev| {
|
|
||||||
ev.stop_propagation();
|
|
||||||
ev.prevent_default();
|
|
||||||
let last_day_of_prev_month = current.with_day0(0).unwrap() - Duration::days(1);
|
|
||||||
|
|
||||||
let date = last_day_of_prev_month
|
|
||||||
.with_day0(timestamp.day0())
|
|
||||||
.unwrap_or(last_day_of_prev_month);
|
|
||||||
Msg::StyledDateTimeInputChanged(
|
|
||||||
field_id,
|
|
||||||
StyledDateTimeChanged::MonthChanged(Some(date)),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
StyledButton {
|
|
||||||
on_click: Some(on_click_left),
|
|
||||||
icon: Some(Icon::DoubleLeft.into_node()),
|
|
||||||
variant: ButtonVariant::Empty,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node()
|
|
||||||
};
|
|
||||||
let right_action = {
|
|
||||||
let field_id = values.field_id.clone();
|
|
||||||
let current = timestamp;
|
|
||||||
let on_click_right = mouse_ev(Ev::Click, move |ev| {
|
|
||||||
ev.stop_propagation();
|
|
||||||
ev.prevent_default();
|
|
||||||
let first_day_of_next_month = (current + Duration::days(32)).with_day0(0).unwrap();
|
|
||||||
let last_day_of_next_month = (first_day_of_next_month + Duration::days(32))
|
|
||||||
.with_day0(0)
|
|
||||||
.unwrap()
|
|
||||||
- Duration::days(1);
|
|
||||||
let date = first_day_of_next_month
|
|
||||||
.with_day0(timestamp.day0())
|
|
||||||
.unwrap_or(last_day_of_next_month);
|
|
||||||
Msg::StyledDateTimeInputChanged(
|
|
||||||
field_id,
|
|
||||||
StyledDateTimeChanged::MonthChanged(Some(date)),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
StyledButton {
|
|
||||||
on_click: Some(on_click_right),
|
|
||||||
icon: Some(Icon::DoubleRight.into_node()),
|
|
||||||
variant: ButtonVariant::Empty,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node()
|
|
||||||
};
|
|
||||||
|
|
||||||
let header_text = current.format("%B %Y").to_string();
|
|
||||||
|
|
||||||
let tooltip = StyledTooltip {
|
|
||||||
visible: values.popup_visible,
|
|
||||||
class_list: "",
|
|
||||||
children: vec![
|
|
||||||
h2![left_action, span![header_text], right_action],
|
|
||||||
div![
|
|
||||||
C!["calendar"],
|
|
||||||
div![
|
|
||||||
C!["weekHeader week"],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Mon).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Tue).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Wed).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Thu).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Fri).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Sat).as_str()],
|
|
||||||
div![C!["day"], format!("{}", Weekday::Sun).as_str()],
|
|
||||||
],
|
|
||||||
weeks
|
|
||||||
],
|
],
|
||||||
],
|
format!("{}", self.current.day()).as_str(),
|
||||||
variant: TooltipVariant::DateTimeBuilder,
|
on_click,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
.into_node();
|
|
||||||
|
|
||||||
let input = {
|
fn is_selected(&self) -> bool {
|
||||||
let field_id = values.field_id.clone();
|
*self.timestamp == *self.current
|
||||||
let visible = values.popup_visible;
|
}
|
||||||
let on_focus = ev(Ev::Click, move |ev| {
|
|
||||||
ev.prevent_default();
|
|
||||||
ev.stop_propagation();
|
|
||||||
Msg::StyledDateTimeInputChanged(
|
|
||||||
field_id,
|
|
||||||
StyledDateTimeChanged::PopupVisibilityChanged(!visible),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let text = values
|
|
||||||
.timestamp
|
|
||||||
.unwrap_or_else(|| Utc::now().naive_utc())
|
|
||||||
.date()
|
|
||||||
.format("%d/%m/%Y")
|
|
||||||
.to_string();
|
|
||||||
StyledButton {
|
|
||||||
on_click: Some(on_focus),
|
|
||||||
text: Some(text.as_str()),
|
|
||||||
variant: ButtonVariant::Empty,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.into_node()
|
|
||||||
};
|
|
||||||
|
|
||||||
div![
|
|
||||||
C!["styledDateTimeInput"],
|
|
||||||
attrs![At::Class => format!("{}", values.field_id).as_str()],
|
|
||||||
input,
|
|
||||||
tooltip,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn day_cell(
|
|
||||||
field_id: &FieldId,
|
|
||||||
timestamp: &NaiveDateTime,
|
|
||||||
current: &NaiveDateTime,
|
|
||||||
current_month_range: &RangeInclusive<NaiveDateTime>,
|
|
||||||
) -> Node<Msg> {
|
|
||||||
let selected_day_class = if *timestamp == *current {
|
|
||||||
"selected"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
let on_click = {
|
|
||||||
let field_id = field_id.clone();
|
|
||||||
let date = *current;
|
|
||||||
ev(Ev::Click, move |ev| {
|
|
||||||
ev.stop_propagation();
|
|
||||||
ev.prevent_default();
|
|
||||||
Msg::StyledDateTimeInputChanged(field_id, StyledDateTimeChanged::DayChanged(Some(date)))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
div![
|
|
||||||
C!["day"],
|
|
||||||
attrs![At::Class => format!("{}", current.weekday())],
|
|
||||||
if current_month_range.contains(¤t) {
|
|
||||||
C!["inCurrentMonth"]
|
|
||||||
} else {
|
|
||||||
C!["outCurrentMonth"]
|
|
||||||
},
|
|
||||||
C![selected_day_class],
|
|
||||||
format!("{}", current.day()).as_str(),
|
|
||||||
on_click,
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -44,22 +44,24 @@ pub struct StyledTooltip<'l> {
|
|||||||
pub variant: TooltipVariant,
|
pub variant: TooltipVariant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l> ToNode for StyledTooltip<'l> {
|
impl<'l> StyledTooltip<'l> {
|
||||||
fn into_node(self) -> Node<Msg> {
|
pub fn render(self) -> Node<Msg> {
|
||||||
render(self)
|
let StyledTooltip {
|
||||||
|
visible,
|
||||||
|
class_list,
|
||||||
|
children,
|
||||||
|
variant,
|
||||||
|
} = self;
|
||||||
|
if visible {
|
||||||
|
div![C!["styledTooltip", class_list, variant.to_str()], children]
|
||||||
|
} else {
|
||||||
|
empty!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(values: StyledTooltip) -> Node<Msg> {
|
impl<'l> ToNode for StyledTooltip<'l> {
|
||||||
let StyledTooltip {
|
fn into_node(self) -> Node<Msg> {
|
||||||
visible,
|
self.render()
|
||||||
class_list,
|
|
||||||
children,
|
|
||||||
variant,
|
|
||||||
} = values;
|
|
||||||
if visible {
|
|
||||||
div![C!["styledTooltip", class_list, variant.to_str()], children]
|
|
||||||
} else {
|
|
||||||
empty!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user