Skip to main content

orbital_base_components/anchor/
offset_target.rs

1use web_sys::Element;
2
3#[cfg(any(feature = "hydrate", not(feature = "ssr")))]
4use leptos::prelude::document;
5#[cfg(any(feature = "hydrate", not(feature = "ssr")))]
6use web_sys::DomRect;
7
8/// Scroll container used to calculate anchor link offsets.
9pub enum OffsetTarget {
10    Selector(String),
11    Element(Element),
12}
13
14impl From<&'static str> for OffsetTarget {
15    fn from(value: &'static str) -> Self {
16        Self::Selector(value.to_string())
17    }
18}
19
20impl From<String> for OffsetTarget {
21    fn from(value: String) -> Self {
22        Self::Selector(value)
23    }
24}
25
26impl From<Element> for OffsetTarget {
27    fn from(value: Element) -> Self {
28        Self::Element(value)
29    }
30}
31
32#[cfg(any(feature = "hydrate", not(feature = "ssr")))]
33impl OffsetTarget {
34    pub(crate) fn element(&self) -> Option<Element> {
35        match self {
36            OffsetTarget::Selector(selector) => document().query_selector(selector).ok().flatten(),
37            OffsetTarget::Element(el) => Some(el.clone()),
38        }
39    }
40
41    pub(crate) fn bounding_client_rect(&self) -> Option<DomRect> {
42        self.element().map(|el| el.get_bounding_client_rect())
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::OffsetTarget;
49
50    #[test]
51    fn offset_target_from_static_str() {
52        match OffsetTarget::from("#scroll") {
53            OffsetTarget::Selector(value) => assert_eq!(value, "#scroll"),
54            _ => panic!("expected selector variant"),
55        }
56    }
57}