use floating_ui_dom::{
ARROW_NAME, Arrow as CoreArrow, ArrowOptions as CoreArrowOptions, Middleware, MiddlewareReturn,
MiddlewareState, Padding,
};
use leptos::prelude::*;
use leptos_node_ref::AnyNodeRef;
use web_sys::wasm_bindgen::JsCast;
#[derive(Clone)]
pub struct ArrowOptions {
pub element: AnyNodeRef,
pub padding: Option<Padding>,
}
impl ArrowOptions {
pub fn new(element: AnyNodeRef) -> Self {
ArrowOptions {
element,
padding: None,
}
}
pub fn element(mut self, value: AnyNodeRef) -> Self {
self.element = value;
self
}
pub fn padding(mut self, value: Padding) -> Self {
self.padding = Some(value);
self
}
}
impl PartialEq for ArrowOptions {
fn eq(&self, other: &Self) -> bool {
self.element.get_untracked() == other.element.get_untracked()
&& self.padding == other.padding
}
}
#[derive(Clone, PartialEq)]
pub struct Arrow {
options: ArrowOptions,
}
impl Arrow {
pub fn new(options: ArrowOptions) -> Self {
Arrow { options }
}
}
impl Middleware<web_sys::Element, web_sys::Window> for Arrow {
fn name(&self) -> &'static str {
ARROW_NAME
}
fn compute(
&self,
state: MiddlewareState<web_sys::Element, web_sys::Window>,
) -> MiddlewareReturn {
let element = self
.options
.element
.get_untracked()
.and_then(|element| element.dyn_into::<web_sys::Element>().ok());
if let Some(element) = element {
CoreArrow::new(CoreArrowOptions {
element,
padding: self.options.padding.clone(),
})
.compute(state)
} else {
MiddlewareReturn {
x: None,
y: None,
data: None,
reset: None,
}
}
}
}