leptos_motion/lib.rs
1//! # Leptos Motion
2//!
3//! A comprehensive animation library for Leptos with Framer Motion-inspired API.
4//!
5//! ## Features
6//!
7//! - **Declarative animations** with Motion-style API
8//! - **Hardware acceleration** via Web Animations API with RAF fallback
9//! - **Gesture support** for drag, hover, tap, and more
10//! - **Layout animations** using FLIP technique
11//! - **Scroll animations** with intersection observers
12//! - **Type safety** with full Rust compile-time validation
13//! - **High performance** targeting 60fps for 100+ concurrent animations
14//! - **Animation presets** for common patterns
15//! - **Keyframe animations** for complex multi-step animations
16//! - **Variants** for named animation states
17//!
18//! ## Quick Start
19//!
20//! ```rust,no_run
21//! use leptos::*;
22//! use leptos_motion::*;
23//! use std::collections::HashMap;
24//!
25//! #[component]
26//! fn App() -> impl IntoView {
27//! let mut initial = HashMap::new();
28//! initial.insert("opacity".to_string(), AnimationValue::Number(0.0));
29//! initial.insert("scale".to_string(), AnimationValue::Number(0.5));
30//!
31//! let mut animate = HashMap::new();
32//! animate.insert("opacity".to_string(), AnimationValue::Number(1.0));
33//! animate.insert("scale".to_string(), AnimationValue::Number(1.0));
34//!
35//! view! {
36//! <MotionDiv
37//! class="my-element".to_string()
38//! initial=initial
39//! animate=animate
40//! transition=Transition {
41//! duration: Some(0.5),
42//! ease: Easing::EaseOut,
43//! delay: None,
44//! repeat: RepeatConfig::Never,
45//! stagger: None,
46//! }
47//! >
48//! "Hello Leptos Motion!"
49//! </MotionDiv>
50//! }
51//! }
52//! ```
53//!
54//! ## Core Concepts
55//!
56//! ### Animation Values
57//!
58//! Animation values represent different types of animatable properties:
59//!
60//! ```rust,no_run
61//! use leptos_motion::*;
62//!
63//! let opacity = AnimationValue::Number(1.0);
64//! let position = AnimationValue::Pixels(100.0);
65//! let rotation = AnimationValue::Degrees(45.0);
66//! let color = AnimationValue::Color("#ff0000".to_string());
67//! ```
68//!
69//! ### Transitions
70//!
71//! Configure how animations behave:
72//!
73//! ```rust,no_run
74//! # use leptos_motion::*;
75//! // Spring animation
76//! let spring = Transition {
77//! ease: Easing::Spring(SpringConfig {
78//! stiffness: 100.0,
79//! damping: 10.0,
80//! mass: 1.0,
81//! ..Default::default()
82//! }),
83//! ..Default::default()
84//! };
85//!
86//! // Tween animation
87//! let tween = Transition {
88//! duration: Some(0.3),
89//! ease: Easing::EaseInOut,
90//! delay: Some(0.1),
91//! ..Default::default()
92//! };
93//! ```
94//!
95//! ### Gestures
96//!
97//! Add interactivity to your animations:
98//!
99//! ```rust,no_run
100//! # use leptos::*;
101//! # use leptos_motion::*;
102//! # use std::collections::HashMap;
103//! # fn main() {
104//! let mut hover_target = HashMap::new();
105//! hover_target.insert("scale".to_string(), AnimationValue::Number(1.1));
106//!
107//! let mut tap_target = HashMap::new();
108//! tap_target.insert("scale".to_string(), AnimationValue::Number(0.9));
109//!
110//! let _view = view! {
111//! <MotionDiv
112//! while_hover=hover_target
113//! while_tap=tap_target
114//! drag=DragConfig::default()
115//! >
116//! "Interactive element"
117//! </MotionDiv>
118//! };
119//! # }
120//! ```
121
122#![warn(missing_docs)]
123#![forbid(unsafe_code)]
124
125// Re-export core functionality
126pub use leptos_motion_core::{
127 AnimationConfig, AnimationEngine, AnimationHandle, AnimationValue, Easing, RepeatConfig,
128 Result, SpringConfig, Transition, animation, easing, spring,
129};
130
131// Re-export performance module if available
132#[cfg(feature = "performance-metrics")]
133pub use leptos_motion_core::performance;
134
135// Re-export DOM functionality
136pub use leptos_motion_dom::{
137 AnimatePresence, DragAxis, DragConfig, DragConstraints, MotionDiv, MotionProps, MotionSpan,
138 PresenceMode,
139};
140
141// Re-export macros
142pub use leptos_motion_macros::motion_target;
143
144#[cfg(feature = "gestures")]
145pub use leptos_motion_gestures::*;
146
147#[cfg(feature = "layout")]
148pub use leptos_motion_layout::*;
149
150#[cfg(feature = "scroll")]
151pub use leptos_motion_scroll::*;
152
153pub use leptos_motion_macros::*;
154
155/// Animation presets and common patterns
156pub mod presets {
157 // Core animation presets
158 pub use leptos_motion_core::animation::presets::*;
159 pub use leptos_motion_core::easing::presets::*;
160 pub use leptos_motion_core::spring::presets::*;
161}
162
163/// Re-export commonly used external types
164pub mod external {
165 pub use leptos::*;
166 pub use wasm_bindgen::prelude::*;
167 pub use web_sys::{Element, Event, HtmlElement, MouseEvent, TouchEvent};
168}
169
170/// Version information
171pub const VERSION: &str = env!("CARGO_PKG_VERSION");
172
173/// Library information
174pub const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
181 fn test_version() {
182 // VERSION and DESCRIPTION are compile-time constants
183 // This test just verifies the constants are defined and have content
184 assert!(VERSION.contains("0.8") || DESCRIPTION.contains("motion"));
185 }
186
187 #[test]
188 fn test_animation_value_creation() {
189 let opacity = AnimationValue::Number(1.0);
190 let position = AnimationValue::Pixels(100.0);
191 let rotation = AnimationValue::Degrees(45.0);
192
193 assert_eq!(opacity, AnimationValue::Number(1.0));
194 assert_eq!(position, AnimationValue::Pixels(100.0));
195 assert_eq!(rotation, AnimationValue::Degrees(45.0));
196 }
197
198 #[test]
199 fn test_transition_creation() {
200 let transition = Transition {
201 duration: Some(1.0),
202 ease: Easing::Spring(SpringConfig::default()),
203 ..Default::default()
204 };
205
206 assert_eq!(transition.duration, Some(1.0));
207 assert!(matches!(transition.ease, Easing::Spring(_)));
208 }
209}