mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
fix: the position is messed up when switching DatePicker panels (#240)
This commit is contained in:
parent
b476835c11
commit
7b29f7da37
5 changed files with 63 additions and 17 deletions
|
@ -1,8 +1,9 @@
|
||||||
use super::PanelVariant;
|
use super::PanelVariant;
|
||||||
use crate::{Button, ButtonAppearance, ButtonSize, CalendarItemDate};
|
use crate::{Button, ButtonAppearance, ButtonSize, CalendarItemDate};
|
||||||
use chrono::{Datelike, Days, Month, Months, NaiveDate};
|
use chrono::{Datelike, Days, Month, Months, NaiveDate};
|
||||||
use leptos::prelude::*;
|
use leptos::{html, prelude::*};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use thaw_components::FollowerInjection;
|
||||||
use thaw_utils::{now_date, ArcOneCallback};
|
use thaw_utils::{now_date, ArcOneCallback};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -12,6 +13,14 @@ pub fn DatePanel(
|
||||||
close_panel: ArcOneCallback<Option<NaiveDate>>,
|
close_panel: ArcOneCallback<Option<NaiveDate>>,
|
||||||
panel_variant: RwSignal<PanelVariant>,
|
panel_variant: RwSignal<PanelVariant>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
|
let follower = FollowerInjection::expect_context();
|
||||||
|
let panel_ref = NodeRef::<html::Div>::new();
|
||||||
|
Effect::new(move || {
|
||||||
|
let Some(_) = panel_ref.get() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
follower.refresh_position();
|
||||||
|
});
|
||||||
let dates = Memo::new(move |_| {
|
let dates = Memo::new(move |_| {
|
||||||
let show_date = show_date.get();
|
let show_date = show_date.get();
|
||||||
let show_date_month = show_date.month();
|
let show_date_month = show_date.month();
|
||||||
|
@ -87,7 +96,7 @@ pub fn DatePanel(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
<div>
|
<div class="thaw-date-picker-date-panel" node_ref=panel_ref>
|
||||||
<div class="thaw-date-picker-date-panel__calendar">
|
<div class="thaw-date-picker-date-panel__calendar">
|
||||||
<div class="thaw-date-picker-date-panel__header">
|
<div class="thaw-date-picker-date-panel__header">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
use super::PanelVariant;
|
use super::PanelVariant;
|
||||||
use crate::{Button, ButtonAppearance, ButtonSize};
|
use crate::{Button, ButtonAppearance, ButtonSize};
|
||||||
use chrono::{Datelike, Month, Months, NaiveDate};
|
use chrono::{Datelike, Month, Months, NaiveDate};
|
||||||
use leptos::prelude::*;
|
use leptos::{html, prelude::*};
|
||||||
|
use thaw_components::FollowerInjection;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn MonthPanel(
|
pub fn MonthPanel(
|
||||||
date_panel_show_date: RwSignal<NaiveDate>,
|
date_panel_show_date: RwSignal<NaiveDate>,
|
||||||
panel_variant: RwSignal<PanelVariant>,
|
panel_variant: RwSignal<PanelVariant>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
|
let follower = FollowerInjection::expect_context();
|
||||||
|
let panel_ref = NodeRef::<html::Div>::new();
|
||||||
|
Effect::new(move || {
|
||||||
|
let Some(_) = panel_ref.get() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
follower.refresh_position();
|
||||||
|
});
|
||||||
|
|
||||||
let show_date = RwSignal::new(date_panel_show_date.get_untracked());
|
let show_date = RwSignal::new(date_panel_show_date.get_untracked());
|
||||||
let previous_year = move |_| {
|
let previous_year = move |_| {
|
||||||
show_date.update(|date| {
|
show_date.update(|date| {
|
||||||
|
@ -20,7 +30,7 @@ pub fn MonthPanel(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
<div class="thaw-date-picker-month-panel">
|
<div class="thaw-date-picker-month-panel" node_ref=panel_ref>
|
||||||
<div class="thaw-date-picker-month-panel__header">
|
<div class="thaw-date-picker-month-panel__header">
|
||||||
<Button
|
<Button
|
||||||
appearance=ButtonAppearance::Transparent
|
appearance=ButtonAppearance::Transparent
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use super::PanelVariant;
|
use super::PanelVariant;
|
||||||
use crate::{Button, ButtonAppearance, ButtonSize};
|
use crate::{Button, ButtonAppearance, ButtonSize};
|
||||||
use chrono::{Datelike, NaiveDate};
|
use chrono::{Datelike, NaiveDate};
|
||||||
use leptos::prelude::*;
|
use leptos::{html, prelude::*};
|
||||||
|
use thaw_components::FollowerInjection;
|
||||||
|
|
||||||
const MAX_YEAR: i32 = (i32::MAX >> 13) / 10 - 1;
|
const MAX_YEAR: i32 = (i32::MAX >> 13) / 10 - 1;
|
||||||
const MIN_YEAR: i32 = (i32::MIN >> 13) / 10 + 1;
|
const MIN_YEAR: i32 = (i32::MIN >> 13) / 10 + 1;
|
||||||
|
@ -11,6 +12,14 @@ pub fn YearPanel(
|
||||||
date_panel_show_date: RwSignal<NaiveDate>,
|
date_panel_show_date: RwSignal<NaiveDate>,
|
||||||
panel_variant: RwSignal<PanelVariant>,
|
panel_variant: RwSignal<PanelVariant>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
|
let follower = FollowerInjection::expect_context();
|
||||||
|
let panel_ref = NodeRef::<html::Div>::new();
|
||||||
|
Effect::new(move || {
|
||||||
|
let Some(_) = panel_ref.get() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
follower.refresh_position();
|
||||||
|
});
|
||||||
let show_min_year = RwSignal::new(date_panel_show_date.get_untracked().year() / 10);
|
let show_min_year = RwSignal::new(date_panel_show_date.get_untracked().year() / 10);
|
||||||
let previous_year_range = move |_| {
|
let previous_year_range = move |_| {
|
||||||
show_min_year.update(|year| {
|
show_min_year.update(|year| {
|
||||||
|
@ -27,7 +36,7 @@ pub fn YearPanel(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
<div>
|
<div class="thaw-date-picker-year-panel" node_ref=panel_ref>
|
||||||
<div class="thaw-date-picker-year-panel__header">
|
<div class="thaw-date-picker-year-panel__header">
|
||||||
<Button
|
<Button
|
||||||
appearance=ButtonAppearance::Transparent
|
appearance=ButtonAppearance::Transparent
|
||||||
|
|
|
@ -8,6 +8,7 @@ use web_sys::wasm_bindgen::JsCast;
|
||||||
use crate::Teleport;
|
use crate::Teleport;
|
||||||
use get_placement_style::{get_follower_placement_offset, FollowerPlacementOffset};
|
use get_placement_style::{get_follower_placement_offset, FollowerPlacementOffset};
|
||||||
use leptos::{
|
use leptos::{
|
||||||
|
context::Provider,
|
||||||
ev,
|
ev,
|
||||||
html::{self, ElementType},
|
html::{self, ElementType},
|
||||||
leptos_dom::helpers::WindowListenerHandle,
|
leptos_dom::helpers::WindowListenerHandle,
|
||||||
|
@ -187,23 +188,40 @@ where
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
on_cleanup(move || {
|
Owner::on_cleanup(move || {
|
||||||
remove_listener();
|
remove_listener();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let follower_injection = FollowerInjection(Callback::new(move |_| sync_position()));
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
{children()}
|
{children()}
|
||||||
<Teleport immediate=follower_show>
|
<Teleport immediate=follower_show>
|
||||||
<div class="thaw-binder-follower-container">
|
<Provider value=follower_injection>
|
||||||
<div
|
<div class="thaw-binder-follower-container">
|
||||||
class="thaw-binder-follower-content"
|
<div
|
||||||
data-thaw-placement=move || placement_str.get()
|
class="thaw-binder-follower-content"
|
||||||
node_ref=content_ref
|
data-thaw-placement=move || placement_str.get()
|
||||||
style=move || content_style.get()
|
node_ref=content_ref
|
||||||
>
|
style=move || content_style.get()
|
||||||
{follower_children()}
|
>
|
||||||
|
{follower_children()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Provider>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FollowerInjection(Callback<()>);
|
||||||
|
|
||||||
|
impl FollowerInjection {
|
||||||
|
pub fn expect_context() -> Self {
|
||||||
|
expect_context()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh_position(&self) {
|
||||||
|
self.0.run(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod if_comp;
|
||||||
mod option_comp;
|
mod option_comp;
|
||||||
mod teleport;
|
mod teleport;
|
||||||
|
|
||||||
pub use binder::{Binder, Follower, FollowerPlacement, FollowerWidth};
|
pub use binder::{Binder, Follower, FollowerInjection, FollowerPlacement, FollowerWidth};
|
||||||
pub use css_transition::CSSTransition;
|
pub use css_transition::CSSTransition;
|
||||||
pub use focus_trap::FocusTrap;
|
pub use focus_trap::FocusTrap;
|
||||||
pub use if_comp::{ElseIf, If, Then};
|
pub use if_comp::{ElseIf, If, Then};
|
||||||
|
|
Loading…
Add table
Reference in a new issue