floating-ui 0.0.1

Rust bindings for Floating UI
Documentation
use js_sys::Object;
use wasm_bindgen::JsValue;

use crate::{
    utils::{Coords, Placement, SideObject},
    utils_::object_utils,
    Error, Result,
};

#[derive(Clone)]
pub struct MiddlewareData {
    pub obj: Object,
    pub arrow: Option<Arrow>,
    pub auto_placement: Option<AutoPlacement>,
    pub flip: Option<Flip>,
    pub hide: Option<Hide>,
    pub offset: Option<Offset>,
    pub shift: Option<Coords>,
}

impl MiddlewareData {
    pub fn new() -> Self {
        Self {
            obj: Object::new(),
            arrow: None,
            auto_placement: None,
            flip: None,
            hide: None,
            offset: None,
            shift: None,
        }
    }

    pub fn get(&self, key: &str) -> Result<JsValue> {
        object_utils::get_js_value(&self.obj, key)
    }

    pub fn set<T>(&mut self, key: &str, value: T) -> Result<()>
    where
        T: Into<JsValue>,
    {
        object_utils::set_js_value(&self.obj, key, &value.into())
    }

    pub fn with<T>(mut self, key: &str, value: T) -> Result<Self>
    where
        T: Into<JsValue>,
    {
        self.set(key, value)?;
        Ok(self)
    }

    pub fn arrow_x(mut self, x: f64) -> Self {
        self.arrow = Some(arrow::Arrow {
            x: Some(x),
            ..self.arrow.unwrap_or_default()
        });
        self
    }

    pub fn arrow_y(mut self, y: f64) -> Self {
        self.arrow = Some(arrow::Arrow {
            y: Some(y),
            ..self.arrow.unwrap_or_default()
        });
        self
    }

    pub fn arrow_center_offset(mut self, center_offset: f64) -> Self {
        self.arrow = Some(arrow::Arrow {
            center_offset: Some(center_offset),
            ..self.arrow.unwrap_or_default()
        });
        self
    }

    pub fn arrow_alignment_offset(mut self, alignment_offset: f64) -> Self {
        self.arrow = Some(arrow::Arrow {
            alignment_offset: Some(alignment_offset),
            ..self.arrow.unwrap_or_default()
        });
        self
    }

    pub fn auto_placement_index(mut self, index: f64) -> Self {
        self.auto_placement = Some(auto_placement::AutoPlacement {
            index: Some(index),
            ..self.auto_placement.unwrap_or_default()
        });
        self
    }

    pub fn auto_placement_overflow(mut self, placement: Placement, overflows: Vec<f64>) -> Self {
        let overflow_item = auto_placement::OverflowItem {
            placement,
            overflows,
        };
        self.auto_placement = Some(auto_placement::AutoPlacement {
            overflows: vec![overflow_item],
            ..self.auto_placement.unwrap_or_default()
        });
        self
    }

    pub fn flip_index(mut self, index: f64) -> Self {
        self.flip = Some(auto_placement::AutoPlacement {
            index: Some(index),
            ..self.flip.unwrap_or_default()
        });
        self
    }

    pub fn flip_overflow(mut self, placement: Placement, overflows: Vec<f64>) -> Self {
        let overflow_item = auto_placement::OverflowItem {
            placement,
            overflows,
        };
        self.flip = Some(auto_placement::AutoPlacement {
            overflows: vec![overflow_item],
            ..self.flip.unwrap_or_default()
        });
        self
    }

    pub fn hide_reference_hidden(mut self) -> Self {
        self.hide = Some(hide::Hide {
            reference_hidden: Some(true),
            ..self.hide.unwrap_or_default()
        });
        self
    }

    pub fn hide_escaped(mut self) -> Self {
        self.hide = Some(hide::Hide {
            escaped: Some(true),
            ..self.hide.unwrap_or_default()
        });
        self
    }

    pub fn hide_reference_hidden_offsets(mut self, offsets: SideObject) -> Self {
        self.hide = Some(hide::Hide {
            reference_hidden_offsets: Some(offsets),
            ..self.hide.unwrap_or_default()
        });
        self
    }

    pub fn hide_escaped_offsets(mut self, offsets: SideObject) -> Self {
        self.hide = Some(hide::Hide {
            escaped_offsets: Some(offsets),
            ..self.hide.unwrap_or_default()
        });
        self
    }

    pub fn offset(mut self, x: f64, y: f64, placement: Placement) -> Self {
        self.offset = Some(offset::Offset { x, y, placement });
        self
    }

    pub fn shift(mut self, x: f64, y: f64) -> Self {
        self.shift = Some(Coords { x, y });
        self
    }
}

impl TryFrom<JsValue> for MiddlewareData {
    type Error = Error;

    fn try_from(value: JsValue) -> Result<Self> {
        let obj = Object::from(value);

        let arrow = object_utils::try_get_option::<Arrow>(&obj, "arrow")?;
        let auto_placement = object_utils::try_get_option::<AutoPlacement>(&obj, "autoPlacement")?;
        let flip = object_utils::try_get_option::<Flip>(&obj, "flip")?;
        let hide = object_utils::try_get_option::<Hide>(&obj, "hide")?;
        let offset = object_utils::try_get_option::<Offset>(&obj, "offset")?;
        let shift = object_utils::try_get_option::<Coords>(&obj, "shift")?;

        Ok(Self {
            obj,
            arrow,
            auto_placement,
            flip,
            hide,
            offset,
            shift,
        })
    }
}

impl TryInto<JsValue> for MiddlewareData {
    type Error = Error;

    fn try_into(self) -> Result<JsValue> {
        let obj = self.obj.clone();

        object_utils::try_set_option_js_value(&obj, "arrow", self.arrow)?;
        object_utils::try_set_option_js_value(&obj, "autoPlacement", self.auto_placement)?;
        object_utils::try_set_option_js_value(&obj, "flip", self.flip)?;
        object_utils::try_set_option_js_value(&obj, "hide", self.hide)?;
        object_utils::try_set_option_js_value(&obj, "offset", self.offset)?;

        Ok(obj.into())
    }
}

mod arrow;
pub use arrow::Arrow;

mod auto_placement;
pub use auto_placement::{AutoPlacement, OverflowItem};

pub type Flip = AutoPlacement;

mod hide;
pub use hide::Hide;

mod offset;
pub use offset::Offset;