use web_sys::HtmlElement;
use yew::prelude::*;
use wasm_bindgen::JsCast;
#[derive(Properties, PartialEq)]
pub struct Props {
pub calendar_id: AttrValue,
#[prop_or_default]
pub calendar_options: crate::options::Options,
#[prop_or_default]
pub on_event_click: Option<Callback<crate::bindings::EventClickInfo>>,
#[prop_or_default]
pub on_date_select: Option<Callback<crate::bindings::SelectionInfo>>,
#[prop_or_default]
pub on_calendar_created: Option<Callback<crate::bindings::Calendar>>,
#[prop_or_default]
pub on_dates_set: Option<Callback<crate::bindings::DateSetEvent>>,
#[prop_or_default]
pub class: Classes,
}
#[function_component(FullCalendarComponent)]
pub fn calendar_component(props: &Props) -> Html {
let calendar_ref = use_node_ref();
let calendar_state = use_mut_ref(|| None::<crate::bindings::Calendar>);
{
let calendar_ref = calendar_ref.clone();
let on_calendar_created = props.on_calendar_created.clone();
let on_event_click = props.on_event_click.clone();
let on_date_select = props.on_date_select.clone();
let on_view_changed = props.on_dates_set.clone();
let options = props.calendar_options.clone();
use_effect_with((), move |()| {
let calendar_created = on_calendar_created.clone();
let event_click = on_event_click.clone();
let date_select = on_date_select.clone();
let view_changed = on_view_changed.clone();
let Some(el) = calendar_ref.cast::<HtmlElement>() else {
return;
};
let el_clone = el.clone();
let calendar_instance = calendar_state.clone();
let initialize = move |_: web_sys::wasm_bindgen::JsValue| {
if let Some(cal) = calendar_instance.borrow().as_ref() {
cal.update_size();
return;
}
let options = {
let mut opt = options.clone();
if let Some(event_cb) = event_click.clone() {
opt = opt.with_event_click(
move |event_value: crate::bindings::EventClickInfo| {
event_cb.emit(event_value);
},
);
}
if let Some(select_cb) = date_select.clone() {
opt =
opt.with_select(move |select_info: crate::bindings::SelectionInfo| {
select_cb.emit(select_info);
});
}
if let Some(view_cb) = view_changed.clone() {
opt = opt.with_date_set(move |date_set: crate::bindings::DateSetEvent| {
view_cb.emit(date_set);
});
}
opt
};
let Ok(options) = options.build() else {
return;
};
let cal = crate::bindings::Calendar::new(&el_clone, options);
cal.render();
calendar_instance.borrow_mut().replace(cal.clone());
if let Some(cb) = calendar_created.clone() {
cb.emit(cal);
}
};
let Ok(observer) =
web_sys::ResizeObserver::new(
&web_sys::wasm_bindgen::closure::Closure::<
dyn FnMut(web_sys::wasm_bindgen::JsValue),
>::new(initialize)
.into_js_value()
.unchecked_into(),
)
else {
return;
};
observer.observe(&el);
});
}
html! {
<div
class={props.class.clone()}
ref={calendar_ref}
/>
}
}