leptos_transition_group 0.2.0

Used to create transitions and animations based on state changes
Documentation
use leptos::prelude::window;

#[derive(PartialEq)]
pub enum AnimationTypes {
    Transition,
    Animation,
}

pub struct CSSTransitionInfo {
    pub types: AnimationTypes,
    pub prop_count: usize,
    pub timeout: u64,
}

pub fn get_transition_info(el: &web_sys::Element) -> Option<CSSTransitionInfo> {
    let styles = window().get_computed_style(el).ok().flatten()?;

    let get_style_properties = |property: &str| {
        styles
            .get_property_value(property)
            .unwrap_or_default()
            .split(", ")
            .map(|s| s.to_string())
            .collect::<Vec<_>>()
    };

    let transition_delays = get_style_properties("transition-delay");
    let transition_durations = get_style_properties("transition-duration");
    let transition_timeout = get_timeout(transition_delays, &transition_durations);
    let animation_delays = get_style_properties("animation-delay");
    let animation_durations = get_style_properties("animation-duration");
    let animation_timeout = get_timeout(animation_delays, &animation_durations);

    let timeout = u64::max(transition_timeout, animation_timeout);
    let (types, prop_count) = if timeout > 0 {
        if transition_timeout > animation_timeout {
            (AnimationTypes::Transition, transition_durations.len())
        } else {
            (AnimationTypes::Animation, animation_durations.len())
        }
    } else {
        return None;
    };

    Some(CSSTransitionInfo {
        types,
        prop_count,
        timeout,
    })
}

fn get_timeout(mut delays: Vec<String>, durations: &Vec<String>) -> u64 {
    while delays.len() < durations.len() {
        delays.append(&mut delays.clone())
    }

    fn to_ms(s: &String) -> u64 {
        if s == "auto" || s.is_empty() {
            return 0;
        }

        let s = if s.ends_with("ms") {
            s.split_at(s.len() - 2).0
        } else {
            s.split_at(s.len() - 1).0
        };

        (s.parse::<f32>().unwrap_or_default() * 1000.0).floor() as u64
    }

    durations
        .iter()
        .enumerate()
        .map(|(i, d)| to_ms(d) + to_ms(&delays[i]))
        .max()
        .unwrap_or_default()
}