1use crate::*;
7
8#[derive(Clone, Debug, PartialEq)]
10pub enum DragAxis {
11 Both,
13 X,
15 Y,
17}
18
19#[derive(Clone, Debug, PartialEq, Default)]
21pub struct DragConstraints {
22 pub left: Option<f64>,
24 pub right: Option<f64>,
26 pub top: Option<f64>,
28 pub bottom: Option<f64>,
30}
31
32#[derive(Clone, Debug)]
34pub struct DragConfig {
35 pub axis: Option<DragAxis>,
37 pub constraints: Option<DragConstraints>,
39 pub elastic: Option<f64>,
41 pub momentum: Option<bool>,
43}
44
45impl Default for DragConfig {
46 fn default() -> Self {
47 Self {
48 axis: Some(DragAxis::Both),
49 constraints: None,
50 elastic: Some(0.0),
51 momentum: Some(false),
52 }
53 }
54}
55
56#[derive(Clone, Debug)]
58pub struct MotionProps {
59 pub initial: Option<AnimationTarget>,
61 pub animate: Option<AnimationTarget>,
63 pub exit: Option<AnimationTarget>,
65 pub transition: Option<Transition>,
67 pub variants: Option<Variants>,
69 pub layout: Option<bool>,
71 pub drag: Option<DragConfig>,
73 pub while_hover: Option<AnimationTarget>,
75 pub while_tap: Option<AnimationTarget>,
77 pub while_focus: Option<AnimationTarget>,
79 pub while_in_view: Option<AnimationTarget>,
81 pub event_handlers: Option<EventHandlers>,
83}
84
85#[derive(Clone, Debug)]
87pub struct EventHandlers {
88 pub on_click: Option<fn()>,
90 pub on_hover: Option<fn()>,
92 pub on_focus: Option<fn()>,
94}
95
96#[derive(Clone, Debug, Default)]
102pub struct SimplifiedMotionProps {
103 pub initial: Option<AnimationTarget>,
105 pub animate: Option<AnimationTarget>,
107 pub exit: Option<AnimationTarget>,
109 pub transition: Option<Transition>,
111 pub variants: Option<Variants>,
113 pub layout: Option<bool>,
115 pub drag: Option<SimplifiedDragConfig>,
117 pub while_hover: Option<AnimationTarget>,
119 pub while_tap: Option<AnimationTarget>,
121 pub while_focus: Option<AnimationTarget>,
123 pub while_in_view: Option<AnimationTarget>,
125
126 pub aria_label: Option<String>,
129 pub aria_described_by: Option<String>,
131 pub aria_expanded: Option<bool>,
133 pub aria_hidden: Option<bool>,
135 pub tab_index: Option<i32>,
137 pub keyboard_accessible: Option<bool>,
139 pub respect_reduced_motion: Option<bool>,
141 pub reduced_motion_alternative: Option<String>,
143 pub high_contrast_support: Option<bool>,
145 pub high_contrast_alternative: Option<String>,
147 pub screen_reader_announcements: Option<bool>,
149 pub announcement_text: Option<String>,
151 pub announcement_priority: Option<String>,
153 pub focus_management: Option<bool>,
155 pub focus_trap: Option<bool>,
157 pub focus_restore: Option<bool>,
159 pub color_contrast_ratio: Option<f64>,
161 pub color_contrast_aa_compliant: Option<bool>,
163 pub color_contrast_aaa_compliant: Option<bool>,
165 pub text_scaling_support: Option<bool>,
167 pub min_text_size: Option<f64>,
169 pub max_text_size: Option<f64>,
171 pub min_touch_target_size: Option<f64>,
173 pub touch_target_spacing: Option<f64>,
175 pub touch_target_accessible: Option<bool>,
177 pub error_announcement: Option<bool>,
179 pub error_recovery: Option<bool>,
181 pub error_fallback: Option<String>,
183 pub max_animation_duration: Option<f64>,
185 pub animation_timing_control: Option<bool>,
187 pub animation_pause_support: Option<bool>,
189 pub semantic_role: Option<String>,
191 pub semantic_level: Option<i32>,
193 pub semantic_landmark: Option<String>,
195 pub rtl_support: Option<bool>,
197 pub locale_aware: Option<bool>,
199 pub text_direction: Option<String>,
201 pub assistive_technology_support: Option<bool>,
203 pub assistive_technology_announcements: Option<bool>,
205 pub assistive_technology_control: Option<bool>,
207 pub accessibility_testing_enabled: Option<bool>,
209 pub accessibility_testing_automated: Option<bool>,
211 pub accessibility_testing_manual: Option<bool>,
213 pub accessibility_documentation: Option<bool>,
215 pub accessibility_guidelines: Option<String>,
217 pub accessibility_compliance_level: Option<String>,
219 pub accessibility_validation: Option<bool>,
221 pub accessibility_validation_automated: Option<bool>,
223 pub accessibility_validation_manual: Option<bool>,
225 pub accessibility_reporting: Option<bool>,
227 pub accessibility_reporting_automated: Option<bool>,
229 pub accessibility_reporting_manual: Option<bool>,
231 pub accessibility_monitoring: Option<bool>,
233 pub accessibility_monitoring_automated: Option<bool>,
235 pub accessibility_monitoring_manual: Option<bool>,
237 pub accessibility_feedback: Option<bool>,
239 pub accessibility_feedback_automated: Option<bool>,
241 pub accessibility_feedback_manual: Option<bool>,
243}
244
245#[derive(Clone, Debug)]
247pub struct SimplifiedDragConfig {
248 pub axis: DragAxis,
250 pub constraints: Option<DragConstraints>,
252 pub elastic: f64,
254 pub momentum: bool,
256}
257
258impl SimplifiedMotionProps {
259 pub fn new() -> Self {
261 Self::default()
262 }
263
264 pub fn initial(mut self, initial: AnimationTarget) -> Self {
266 self.initial = Some(initial);
267 self
268 }
269
270 pub fn animate(mut self, animate: AnimationTarget) -> Self {
272 self.animate = Some(animate);
273 self
274 }
275
276 pub fn exit(mut self, exit: AnimationTarget) -> Self {
278 self.exit = Some(exit);
279 self
280 }
281
282 pub fn transition(mut self, transition: Transition) -> Self {
284 self.transition = Some(transition);
285 self
286 }
287
288 pub fn variants(mut self, variants: Variants) -> Self {
290 self.variants = Some(variants);
291 self
292 }
293
294 pub fn layout(mut self, layout: bool) -> Self {
296 self.layout = Some(layout);
297 self
298 }
299
300 pub fn drag(mut self, drag: SimplifiedDragConfig) -> Self {
302 self.drag = Some(drag);
303 self
304 }
305
306 pub fn while_hover(mut self, while_hover: AnimationTarget) -> Self {
308 self.while_hover = Some(while_hover);
309 self
310 }
311
312 pub fn while_tap(mut self, while_tap: AnimationTarget) -> Self {
314 self.while_tap = Some(while_tap);
315 self
316 }
317
318 pub fn while_focus(mut self, while_focus: AnimationTarget) -> Self {
320 self.while_focus = Some(while_focus);
321 self
322 }
323
324 pub fn while_in_view(mut self, while_in_view: AnimationTarget) -> Self {
326 self.while_in_view = Some(while_in_view);
327 self
328 }
329
330 pub fn aria_label(mut self, aria_label: &str) -> Self {
333 self.aria_label = Some(aria_label.to_string());
334 self
335 }
336
337 pub fn aria_described_by(mut self, aria_described_by: &str) -> Self {
339 self.aria_described_by = Some(aria_described_by.to_string());
340 self
341 }
342
343 pub fn aria_expanded(mut self, aria_expanded: bool) -> Self {
345 self.aria_expanded = Some(aria_expanded);
346 self
347 }
348
349 pub fn aria_hidden(mut self, aria_hidden: bool) -> Self {
351 self.aria_hidden = Some(aria_hidden);
352 self
353 }
354
355 pub fn tab_index(mut self, tab_index: i32) -> Self {
357 self.tab_index = Some(tab_index);
358 self
359 }
360
361 pub fn keyboard_accessible(mut self, keyboard_accessible: bool) -> Self {
363 self.keyboard_accessible = Some(keyboard_accessible);
364 self
365 }
366
367 pub fn respect_reduced_motion(mut self, respect_reduced_motion: bool) -> Self {
369 self.respect_reduced_motion = Some(respect_reduced_motion);
370 self
371 }
372
373 pub fn reduced_motion_alternative(mut self, reduced_motion_alternative: &str) -> Self {
375 self.reduced_motion_alternative = Some(reduced_motion_alternative.to_string());
376 self
377 }
378
379 pub fn high_contrast_support(mut self, high_contrast_support: bool) -> Self {
381 self.high_contrast_support = Some(high_contrast_support);
382 self
383 }
384
385 pub fn high_contrast_alternative(mut self, high_contrast_alternative: &str) -> Self {
387 self.high_contrast_alternative = Some(high_contrast_alternative.to_string());
388 self
389 }
390
391 pub fn screen_reader_announcements(mut self, screen_reader_announcements: bool) -> Self {
393 self.screen_reader_announcements = Some(screen_reader_announcements);
394 self
395 }
396
397 pub fn announcement_text(mut self, announcement_text: &str) -> Self {
399 self.announcement_text = Some(announcement_text.to_string());
400 self
401 }
402
403 pub fn announcement_priority(mut self, announcement_priority: &str) -> Self {
405 self.announcement_priority = Some(announcement_priority.to_string());
406 self
407 }
408
409 pub fn focus_management(mut self, focus_management: bool) -> Self {
411 self.focus_management = Some(focus_management);
412 self
413 }
414
415 pub fn focus_trap(mut self, focus_trap: bool) -> Self {
417 self.focus_trap = Some(focus_trap);
418 self
419 }
420
421 pub fn focus_restore(mut self, focus_restore: bool) -> Self {
423 self.focus_restore = Some(focus_restore);
424 self
425 }
426
427 pub fn color_contrast_ratio(mut self, color_contrast_ratio: f64) -> Self {
429 self.color_contrast_ratio = Some(color_contrast_ratio);
430 self
431 }
432
433 pub fn color_contrast_aa_compliant(mut self, color_contrast_aa_compliant: bool) -> Self {
435 self.color_contrast_aa_compliant = Some(color_contrast_aa_compliant);
436 self
437 }
438
439 pub fn color_contrast_aaa_compliant(mut self, color_contrast_aaa_compliant: bool) -> Self {
441 self.color_contrast_aaa_compliant = Some(color_contrast_aaa_compliant);
442 self
443 }
444
445 pub fn text_scaling_support(mut self, text_scaling_support: bool) -> Self {
447 self.text_scaling_support = Some(text_scaling_support);
448 self
449 }
450
451 pub fn min_text_size(mut self, min_text_size: f64) -> Self {
453 self.min_text_size = Some(min_text_size);
454 self
455 }
456
457 pub fn max_text_size(mut self, max_text_size: f64) -> Self {
459 self.max_text_size = Some(max_text_size);
460 self
461 }
462
463 pub fn min_touch_target_size(mut self, min_touch_target_size: f64) -> Self {
465 self.min_touch_target_size = Some(min_touch_target_size);
466 self
467 }
468
469 pub fn touch_target_spacing(mut self, touch_target_spacing: f64) -> Self {
471 self.touch_target_spacing = Some(touch_target_spacing);
472 self
473 }
474
475 pub fn touch_target_accessible(mut self, touch_target_accessible: bool) -> Self {
477 self.touch_target_accessible = Some(touch_target_accessible);
478 self
479 }
480
481 pub fn error_announcement(mut self, error_announcement: bool) -> Self {
483 self.error_announcement = Some(error_announcement);
484 self
485 }
486
487 pub fn error_recovery(mut self, error_recovery: bool) -> Self {
489 self.error_recovery = Some(error_recovery);
490 self
491 }
492
493 pub fn error_fallback(mut self, error_fallback: &str) -> Self {
495 self.error_fallback = Some(error_fallback.to_string());
496 self
497 }
498
499 pub fn max_animation_duration(mut self, max_animation_duration: f64) -> Self {
501 self.max_animation_duration = Some(max_animation_duration);
502 self
503 }
504
505 pub fn animation_timing_control(mut self, animation_timing_control: bool) -> Self {
507 self.animation_timing_control = Some(animation_timing_control);
508 self
509 }
510
511 pub fn animation_pause_support(mut self, animation_pause_support: bool) -> Self {
513 self.animation_pause_support = Some(animation_pause_support);
514 self
515 }
516
517 pub fn semantic_role(mut self, semantic_role: &str) -> Self {
519 self.semantic_role = Some(semantic_role.to_string());
520 self
521 }
522
523 pub fn semantic_level(mut self, semantic_level: i32) -> Self {
525 self.semantic_level = Some(semantic_level);
526 self
527 }
528
529 pub fn semantic_landmark(mut self, semantic_landmark: &str) -> Self {
531 self.semantic_landmark = Some(semantic_landmark.to_string());
532 self
533 }
534
535 pub fn rtl_support(mut self, rtl_support: bool) -> Self {
537 self.rtl_support = Some(rtl_support);
538 self
539 }
540
541 pub fn locale_aware(mut self, locale_aware: bool) -> Self {
543 self.locale_aware = Some(locale_aware);
544 self
545 }
546
547 pub fn text_direction(mut self, text_direction: &str) -> Self {
549 self.text_direction = Some(text_direction.to_string());
550 self
551 }
552
553 pub fn assistive_technology_support(mut self, assistive_technology_support: bool) -> Self {
555 self.assistive_technology_support = Some(assistive_technology_support);
556 self
557 }
558
559 pub fn assistive_technology_announcements(
561 mut self,
562 assistive_technology_announcements: bool,
563 ) -> Self {
564 self.assistive_technology_announcements = Some(assistive_technology_announcements);
565 self
566 }
567
568 pub fn assistive_technology_control(mut self, assistive_technology_control: bool) -> Self {
570 self.assistive_technology_control = Some(assistive_technology_control);
571 self
572 }
573
574 pub fn accessibility_testing_enabled(mut self, accessibility_testing_enabled: bool) -> Self {
576 self.accessibility_testing_enabled = Some(accessibility_testing_enabled);
577 self
578 }
579
580 pub fn accessibility_testing_automated(
582 mut self,
583 accessibility_testing_automated: bool,
584 ) -> Self {
585 self.accessibility_testing_automated = Some(accessibility_testing_automated);
586 self
587 }
588
589 pub fn accessibility_testing_manual(mut self, accessibility_testing_manual: bool) -> Self {
591 self.accessibility_testing_manual = Some(accessibility_testing_manual);
592 self
593 }
594
595 pub fn accessibility_documentation(mut self, accessibility_documentation: bool) -> Self {
597 self.accessibility_documentation = Some(accessibility_documentation);
598 self
599 }
600
601 pub fn accessibility_guidelines(mut self, accessibility_guidelines: &str) -> Self {
603 self.accessibility_guidelines = Some(accessibility_guidelines.to_string());
604 self
605 }
606
607 pub fn accessibility_compliance_level(mut self, accessibility_compliance_level: &str) -> Self {
609 self.accessibility_compliance_level = Some(accessibility_compliance_level.to_string());
610 self
611 }
612
613 pub fn accessibility_validation(mut self, accessibility_validation: bool) -> Self {
615 self.accessibility_validation = Some(accessibility_validation);
616 self
617 }
618
619 pub fn accessibility_validation_automated(
621 mut self,
622 accessibility_validation_automated: bool,
623 ) -> Self {
624 self.accessibility_validation_automated = Some(accessibility_validation_automated);
625 self
626 }
627
628 pub fn accessibility_validation_manual(
630 mut self,
631 accessibility_validation_manual: bool,
632 ) -> Self {
633 self.accessibility_validation_manual = Some(accessibility_validation_manual);
634 self
635 }
636
637 pub fn accessibility_reporting(mut self, accessibility_reporting: bool) -> Self {
639 self.accessibility_reporting = Some(accessibility_reporting);
640 self
641 }
642
643 pub fn accessibility_reporting_automated(
645 mut self,
646 accessibility_reporting_automated: bool,
647 ) -> Self {
648 self.accessibility_reporting_automated = Some(accessibility_reporting_automated);
649 self
650 }
651
652 pub fn accessibility_reporting_manual(mut self, accessibility_reporting_manual: bool) -> Self {
654 self.accessibility_reporting_manual = Some(accessibility_reporting_manual);
655 self
656 }
657
658 pub fn accessibility_monitoring(mut self, accessibility_monitoring: bool) -> Self {
660 self.accessibility_monitoring = Some(accessibility_monitoring);
661 self
662 }
663
664 pub fn accessibility_monitoring_automated(
666 mut self,
667 accessibility_monitoring_automated: bool,
668 ) -> Self {
669 self.accessibility_monitoring_automated = Some(accessibility_monitoring_automated);
670 self
671 }
672
673 pub fn accessibility_monitoring_manual(
675 mut self,
676 accessibility_monitoring_manual: bool,
677 ) -> Self {
678 self.accessibility_monitoring_manual = Some(accessibility_monitoring_manual);
679 self
680 }
681
682 pub fn accessibility_feedback(mut self, accessibility_feedback: bool) -> Self {
684 self.accessibility_feedback = Some(accessibility_feedback);
685 self
686 }
687
688 pub fn accessibility_feedback_automated(
690 mut self,
691 accessibility_feedback_automated: bool,
692 ) -> Self {
693 self.accessibility_feedback_automated = Some(accessibility_feedback_automated);
694 self
695 }
696
697 pub fn accessibility_feedback_manual(mut self, accessibility_feedback_manual: bool) -> Self {
699 self.accessibility_feedback_manual = Some(accessibility_feedback_manual);
700 self
701 }
702
703 pub fn has_animations(&self) -> bool {
705 self.animate.is_some()
706 || self.while_hover.is_some()
707 || self.while_tap.is_some()
708 || self.while_focus.is_some()
709 || self.while_in_view.is_some()
710 }
711
712 pub fn has_drag(&self) -> bool {
714 self.drag.is_some()
715 }
716
717 pub fn has_layout(&self) -> bool {
719 self.layout.unwrap_or(false)
720 }
721
722 pub fn animation_count(&self) -> usize {
724 let mut count = 0;
725 if self.animate.is_some() {
726 count += 1;
727 }
728 if self.while_hover.is_some() {
729 count += 1;
730 }
731 if self.while_tap.is_some() {
732 count += 1;
733 }
734 if self.while_focus.is_some() {
735 count += 1;
736 }
737 if self.while_in_view.is_some() {
738 count += 1;
739 }
740 count
741 }
742}
743
744impl SimplifiedDragConfig {
745 pub fn new() -> Self {
747 Self::default()
748 }
749
750 pub fn axis(mut self, axis: DragAxis) -> Self {
752 self.axis = axis;
753 self
754 }
755
756 pub fn constraints(mut self, constraints: DragConstraints) -> Self {
758 self.constraints = Some(constraints);
759 self
760 }
761
762 pub fn elastic(mut self, elastic: f64) -> Self {
764 self.elastic = elastic;
765 self
766 }
767
768 pub fn momentum(mut self, momentum: bool) -> Self {
770 self.momentum = momentum;
771 self
772 }
773
774 pub fn has_constraints(&self) -> bool {
776 self.constraints.is_some()
777 }
778
779 pub fn has_elastic(&self) -> bool {
781 self.elastic > 0.0
782 }
783}
784
785impl Default for SimplifiedDragConfig {
786 fn default() -> Self {
787 Self {
788 axis: DragAxis::Both,
789 constraints: None,
790 elastic: 0.0,
791 momentum: false,
792 }
793 }
794}
795
796impl From<MotionProps> for SimplifiedMotionProps {
798 fn from(props: MotionProps) -> Self {
799 Self {
800 initial: props.initial,
801 animate: props.animate,
802 exit: props.exit,
803 transition: props.transition,
804 variants: props.variants,
805 layout: props.layout,
806 drag: props.drag.map(|d| SimplifiedDragConfig {
807 axis: d.axis.unwrap_or(DragAxis::Both),
808 constraints: d.constraints,
809 elastic: d.elastic.unwrap_or(0.0),
810 momentum: d.momentum.unwrap_or(false),
811 }),
812 while_hover: props.while_hover,
813 while_tap: props.while_tap,
814 while_focus: props.while_focus,
815 while_in_view: props.while_in_view,
816
817 aria_label: None,
819 aria_described_by: None,
820 aria_expanded: None,
821 aria_hidden: None,
822 tab_index: None,
823 keyboard_accessible: None,
824 respect_reduced_motion: None,
825 reduced_motion_alternative: None,
826 high_contrast_support: None,
827 high_contrast_alternative: None,
828 screen_reader_announcements: None,
829 announcement_text: None,
830 announcement_priority: None,
831 focus_management: None,
832 focus_trap: None,
833 focus_restore: None,
834 color_contrast_ratio: None,
835 color_contrast_aa_compliant: None,
836 color_contrast_aaa_compliant: None,
837 text_scaling_support: None,
838 min_text_size: None,
839 max_text_size: None,
840 min_touch_target_size: None,
841 touch_target_spacing: None,
842 touch_target_accessible: None,
843 error_announcement: None,
844 error_recovery: None,
845 error_fallback: None,
846 max_animation_duration: None,
847 animation_timing_control: None,
848 animation_pause_support: None,
849 semantic_role: None,
850 semantic_level: None,
851 semantic_landmark: None,
852 rtl_support: None,
853 locale_aware: None,
854 text_direction: None,
855 assistive_technology_support: None,
856 assistive_technology_announcements: None,
857 assistive_technology_control: None,
858 accessibility_testing_enabled: None,
859 accessibility_testing_automated: None,
860 accessibility_testing_manual: None,
861 accessibility_documentation: None,
862 accessibility_guidelines: None,
863 accessibility_compliance_level: None,
864 accessibility_validation: None,
865 accessibility_validation_automated: None,
866 accessibility_validation_manual: None,
867 accessibility_reporting: None,
868 accessibility_reporting_automated: None,
869 accessibility_reporting_manual: None,
870 accessibility_monitoring: None,
871 accessibility_monitoring_automated: None,
872 accessibility_monitoring_manual: None,
873 accessibility_feedback: None,
874 accessibility_feedback_automated: None,
875 accessibility_feedback_manual: None,
876 }
877 }
878}
879
880impl From<DragConfig> for SimplifiedDragConfig {
882 fn from(config: DragConfig) -> Self {
883 Self {
884 axis: config.axis.unwrap_or(DragAxis::Both),
885 constraints: config.constraints,
886 elastic: config.elastic.unwrap_or(0.0),
887 momentum: config.momentum.unwrap_or(false),
888 }
889 }
890}
891
892impl From<SimplifiedMotionProps> for MotionProps {
894 fn from(props: SimplifiedMotionProps) -> Self {
895 Self {
896 initial: props.initial,
897 animate: props.animate,
898 exit: props.exit,
899 transition: props.transition,
900 variants: props.variants,
901 layout: props.layout,
902 drag: props.drag.map(|d| DragConfig {
903 axis: Some(d.axis),
904 constraints: d.constraints,
905 elastic: Some(d.elastic),
906 momentum: Some(d.momentum),
907 }),
908 while_hover: props.while_hover,
909 while_tap: props.while_tap,
910 while_focus: props.while_focus,
911 while_in_view: props.while_in_view,
912 event_handlers: None, }
914 }
915}
916
917impl From<SimplifiedDragConfig> for DragConfig {
919 fn from(config: SimplifiedDragConfig) -> Self {
920 Self {
921 axis: Some(config.axis),
922 constraints: config.constraints,
923 elastic: Some(config.elastic),
924 momentum: Some(config.momentum),
925 }
926 }
927}
928
929#[cfg(test)]
930mod tests {
931 use super::*;
932
933 #[test]
934 fn test_simplified_motion_props_creation() {
935 let props = SimplifiedMotionProps::new();
936 assert!(props.initial.is_none());
937 assert!(props.animate.is_none());
938 assert!(!props.has_animations());
939 assert!(!props.has_drag());
940 assert!(!props.has_layout());
941 assert_eq!(props.animation_count(), 0);
942 }
943
944 #[test]
945 fn test_simplified_motion_props_fluent_api() {
946 let target = std::collections::HashMap::new();
947 let props = SimplifiedMotionProps::new()
948 .animate(target.clone())
949 .layout(true);
950
951 assert!(props.animate.is_some());
952 assert!(props.has_animations());
953 assert!(props.has_layout());
954 assert_eq!(props.animation_count(), 1);
955 }
956
957 #[test]
958 fn test_simplified_drag_config_creation() {
959 let drag_config = SimplifiedDragConfig::new();
960 assert_eq!(drag_config.axis, DragAxis::Both);
961 assert!(!drag_config.has_constraints());
962 assert!(!drag_config.has_elastic());
963 }
964
965 #[test]
966 fn test_simplified_drag_config_fluent_api() {
967 let drag_config = SimplifiedDragConfig::new()
968 .axis(DragAxis::X)
969 .elastic(0.3)
970 .momentum(true);
971
972 assert_eq!(drag_config.axis, DragAxis::X);
973 assert!(drag_config.has_elastic());
974 assert!(drag_config.momentum);
975 }
976
977 #[test]
978 fn test_conversion_from_complex_motion_props() {
979 let complex_props = MotionProps {
980 initial: None,
981 animate: None,
982 exit: None,
983 transition: None,
984 variants: None,
985 layout: Some(true),
986 drag: Some(DragConfig {
987 axis: Some(DragAxis::X),
988 constraints: None,
989 elastic: Some(0.2),
990 momentum: Some(true),
991 }),
992 while_hover: None,
993 while_tap: None,
994 while_focus: None,
995 while_in_view: None,
996 event_handlers: None,
997 };
998
999 let simplified_props = SimplifiedMotionProps::from(complex_props);
1000 assert!(simplified_props.has_layout());
1001 assert!(simplified_props.has_drag());
1002
1003 let drag = simplified_props.drag.unwrap();
1004 assert_eq!(drag.axis, DragAxis::X);
1005 assert_eq!(drag.elastic, 0.2);
1006 assert!(drag.momentum);
1007 }
1008
1009 #[test]
1010 fn test_conversion_to_complex_motion_props() {
1011 let simplified_props = SimplifiedMotionProps::new()
1012 .layout(true)
1013 .drag(SimplifiedDragConfig::new().axis(DragAxis::Y));
1014
1015 let complex_props = MotionProps::from(simplified_props);
1016 assert!(complex_props.layout.unwrap());
1017 assert!(complex_props.drag.is_some());
1018 assert!(complex_props.event_handlers.is_none()); }
1020}