mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 14:09:21 -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 crate::{Button, ButtonAppearance, ButtonSize, CalendarItemDate};
|
||||
use chrono::{Datelike, Days, Month, Months, NaiveDate};
|
||||
use leptos::prelude::*;
|
||||
use leptos::{html, prelude::*};
|
||||
use std::ops::Deref;
|
||||
use thaw_components::FollowerInjection;
|
||||
use thaw_utils::{now_date, ArcOneCallback};
|
||||
|
||||
#[component]
|
||||
|
@ -12,6 +13,14 @@ pub fn DatePanel(
|
|||
close_panel: ArcOneCallback<Option<NaiveDate>>,
|
||||
panel_variant: RwSignal<PanelVariant>,
|
||||
) -> 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 show_date = show_date.get();
|
||||
let show_date_month = show_date.month();
|
||||
|
@ -87,7 +96,7 @@ pub fn DatePanel(
|
|||
}
|
||||
};
|
||||
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__header">
|
||||
<Button
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
use super::PanelVariant;
|
||||
use crate::{Button, ButtonAppearance, ButtonSize};
|
||||
use chrono::{Datelike, Month, Months, NaiveDate};
|
||||
use leptos::prelude::*;
|
||||
use leptos::{html, prelude::*};
|
||||
use thaw_components::FollowerInjection;
|
||||
|
||||
#[component]
|
||||
pub fn MonthPanel(
|
||||
date_panel_show_date: RwSignal<NaiveDate>,
|
||||
panel_variant: RwSignal<PanelVariant>,
|
||||
) -> 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 previous_year = move |_| {
|
||||
show_date.update(|date| {
|
||||
|
@ -20,7 +30,7 @@ pub fn MonthPanel(
|
|||
});
|
||||
};
|
||||
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">
|
||||
<Button
|
||||
appearance=ButtonAppearance::Transparent
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use super::PanelVariant;
|
||||
use crate::{Button, ButtonAppearance, ButtonSize};
|
||||
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 MIN_YEAR: i32 = (i32::MIN >> 13) / 10 + 1;
|
||||
|
@ -11,6 +12,14 @@ pub fn YearPanel(
|
|||
date_panel_show_date: RwSignal<NaiveDate>,
|
||||
panel_variant: RwSignal<PanelVariant>,
|
||||
) -> 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 previous_year_range = move |_| {
|
||||
show_min_year.update(|year| {
|
||||
|
@ -27,7 +36,7 @@ pub fn YearPanel(
|
|||
});
|
||||
};
|
||||
view! {
|
||||
<div>
|
||||
<div class="thaw-date-picker-year-panel" node_ref=panel_ref>
|
||||
<div class="thaw-date-picker-year-panel__header">
|
||||
<Button
|
||||
appearance=ButtonAppearance::Transparent
|
||||
|
|
|
@ -8,6 +8,7 @@ use web_sys::wasm_bindgen::JsCast;
|
|||
use crate::Teleport;
|
||||
use get_placement_style::{get_follower_placement_offset, FollowerPlacementOffset};
|
||||
use leptos::{
|
||||
context::Provider,
|
||||
ev,
|
||||
html::{self, ElementType},
|
||||
leptos_dom::helpers::WindowListenerHandle,
|
||||
|
@ -187,23 +188,40 @@ where
|
|||
}
|
||||
});
|
||||
|
||||
on_cleanup(move || {
|
||||
Owner::on_cleanup(move || {
|
||||
remove_listener();
|
||||
});
|
||||
|
||||
let follower_injection = FollowerInjection(Callback::new(move |_| sync_position()));
|
||||
|
||||
view! {
|
||||
{children()}
|
||||
<Teleport immediate=follower_show>
|
||||
<div class="thaw-binder-follower-container">
|
||||
<div
|
||||
class="thaw-binder-follower-content"
|
||||
data-thaw-placement=move || placement_str.get()
|
||||
node_ref=content_ref
|
||||
style=move || content_style.get()
|
||||
>
|
||||
{follower_children()}
|
||||
<Provider value=follower_injection>
|
||||
<div class="thaw-binder-follower-container">
|
||||
<div
|
||||
class="thaw-binder-follower-content"
|
||||
data-thaw-placement=move || placement_str.get()
|
||||
node_ref=content_ref
|
||||
style=move || content_style.get()
|
||||
>
|
||||
{follower_children()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Provider>
|
||||
</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 teleport;
|
||||
|
||||
pub use binder::{Binder, Follower, FollowerPlacement, FollowerWidth};
|
||||
pub use binder::{Binder, Follower, FollowerInjection, FollowerPlacement, FollowerWidth};
|
||||
pub use css_transition::CSSTransition;
|
||||
pub use focus_trap::FocusTrap;
|
||||
pub use if_comp::{ElseIf, If, Then};
|
||||
|
|
Loading…
Add table
Reference in a new issue