Skip to content

Commit

Permalink
feat: Nicer Switch (#848)
Browse files Browse the repository at this point in the history
* feat: Nicer Switch

* feat: color adjustements
  • Loading branch information
marc2332 authored Sep 8, 2024
1 parent f90ae37 commit fe39475
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 50 deletions.
76 changes: 41 additions & 35 deletions crates/components/src/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use freya_elements::{
},
};
use freya_hooks::{
use_animation,
use_animation_with_dependencies,
use_applied_theme,
use_focus,
use_platform,
AnimColor,
AnimNum,
Ease,
Function,
Expand Down Expand Up @@ -64,15 +65,35 @@ pub enum SwitchStatus {
/// ```
#[allow(non_snake_case)]
pub fn Switch(props: SwitchProps) -> Element {
let animation = use_animation(|ctx| {
ctx.with(
AnimNum::new(0., 25.)
.time(300)
.function(Function::Expo)
.ease(Ease::Out),
let theme = use_applied_theme!(&props.theme, switch);
let animation = use_animation_with_dependencies(&theme, |ctx, theme| {
(
ctx.with(
AnimNum::new(2., 22.)
.time(300)
.function(Function::Expo)
.ease(Ease::Out),
),
ctx.with(
AnimNum::new(14., 18.)
.time(300)
.function(Function::Expo)
.ease(Ease::Out),
),
ctx.with(
AnimColor::new(&theme.background, &theme.enabled_background)
.time(300)
.function(Function::Expo)
.ease(Ease::Out),
),
ctx.with(
AnimColor::new(&theme.thumb_background, &theme.enabled_thumb_background)
.time(300)
.function(Function::Expo)
.ease(Ease::Out),
),
)
});
let theme = use_applied_theme!(&props.theme, switch);
let platform = use_platform();
let mut status = use_signal(SwitchStatus::default);
let mut focus = use_focus();
Expand Down Expand Up @@ -113,21 +134,11 @@ pub fn Switch(props: SwitchProps) -> Element {
}
};

let (offset_x, background, circle) = {
if props.enabled {
(
animation.get().read().as_f32(),
theme.enabled_background,
theme.enabled_thumb_background,
)
} else {
(
animation.get().read().as_f32(),
theme.background,
theme.thumb_background,
)
}
};
let offset_x = animation.get().0.read().as_f32();
let size = animation.get().1.read().as_f32();
let background = animation.get().2.read().as_string();
let circle = animation.get().3.read().as_string();

let border = if focus.is_selected() {
if props.enabled {
format!("2 solid {}", theme.enabled_focus_border_fill)
Expand All @@ -149,9 +160,9 @@ pub fn Switch(props: SwitchProps) -> Element {
rsx!(
rect {
margin: "{theme.margin}",
width: "50",
width: "48",
height: "25",
padding: "1",
padding: "4",
corner_radius: "50",
background: "{background}",
border: "{border}",
Expand All @@ -161,18 +172,13 @@ pub fn Switch(props: SwitchProps) -> Element {
onkeydown,
onclick,
focus_id,
offset_x: "{offset_x}",
main_align: "center",
rect {
width: "100%",
height: "100%",
offset_x: "{offset_x}",
padding: "2.5",
background: "{circle}",
width: "{size}",
height: "{size}",
corner_radius: "50",
rect {
background: "{circle}",
width: "18",
height: "18",
corner_radius: "50",
}
}
}
)
Expand Down
8 changes: 4 additions & 4 deletions crates/hooks/src/theming/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ pub const LIGHT_THEME: Theme = Theme {
},
switch: SwitchTheme {
margin: cow_borrowed!("0"),
background: cow_borrowed!("rgb(121, 116, 126)"),
thumb_background: cow_borrowed!("rgb(231, 224, 236)"),
enabled_background: cow_borrowed!("rgb(103, 80, 164)"),
enabled_thumb_background: cow_borrowed!("rgb(234, 221, 255)"),
background: cow_borrowed!("rgb(225, 225, 225)"),
thumb_background: cow_borrowed!("rgb(125, 125, 125)"),
enabled_background: cow_borrowed!("rgb(202, 193, 227)"),
enabled_thumb_background: cow_borrowed!("rgb(103, 80, 164)"),
focus_border_fill: cow_borrowed!("rgb(180, 180, 180)"),
enabled_focus_border_fill: cow_borrowed!("rgb(180, 180, 180)"),
},
Expand Down
30 changes: 30 additions & 0 deletions crates/hooks/src/use_animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ pub struct UseAnimator<Animated: PartialEq + Clone + 'static> {
pub(crate) is_running: Signal<bool>,
pub(crate) has_run_yet: Signal<bool>,
pub(crate) task: Signal<Option<Task>>,
pub(crate) last_direction: Signal<AnimDirection>,
}

impl<T: PartialEq + Clone + 'static> Copy for UseAnimator<T> {}
Expand All @@ -457,6 +458,21 @@ impl<Animated: PartialEq + Clone + 'static> UseAnimator<Animated> {
}
}

/// Update the animation.
pub fn run_update(&self) {
let mut task = self.task;

if let Some(task) = task.write().take() {
task.cancel();
}

for value in &self.value_and_ctx.read().1.animated_values {
let mut value = *value;
let time = value.peek().time().as_millis() as i32;
value.write().advance(time, *self.last_direction.peek());
}
}

/// Checks if there is any animation running.
pub fn is_running(&self) -> bool {
*self.is_running.read()
Expand Down Expand Up @@ -492,6 +508,9 @@ impl<Animated: PartialEq + Clone + 'static> UseAnimator<Animated> {
let mut has_run_yet = self.has_run_yet;
let on_finish = ctx.on_finish;
let mut task = self.task;
let mut last_direction = self.last_direction;

last_direction.set(direction);

// Cancel previous animations
if let Some(task) = task.write().take() {
Expand Down Expand Up @@ -649,6 +668,7 @@ pub fn use_animation<Animated: PartialEq + Clone + 'static>(
let is_running = use_signal(|| false);
let has_run_yet = use_signal(|| false);
let task = use_signal(|| None);
let last_direction = use_signal(|| AnimDirection::Reverse);

let value_and_ctx = use_memo(move || {
let mut ctx = Context::default();
Expand All @@ -661,6 +681,7 @@ pub fn use_animation<Animated: PartialEq + Clone + 'static>(
is_running,
has_run_yet,
task,
last_direction,
};

use_hook(move || {
Expand All @@ -683,6 +704,7 @@ where
let is_running = use_signal(|| false);
let has_run_yet = use_signal(|| false);
let task = use_signal(|| None);
let last_direction = use_signal(|| AnimDirection::Reverse);

let value_and_ctx = use_memo(use_reactive(deps, move |vals| {
let mut ctx = Context::default();
Expand All @@ -695,8 +717,16 @@ where
is_running,
has_run_yet,
task,
last_direction,
};

use_memo(move || {
let _ = value_and_ctx.read();
if *has_run_yet.peek() {
animator.run_update()
}
});

use_hook(move || {
if animator.value_and_ctx.read().1.auto_start {
animator.run(AnimDirection::Forward);
Expand Down
26 changes: 15 additions & 11 deletions examples/switch_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,23 @@ fn app() -> Element {

rsx!(
Body {
theme: theme_with!(BodyTheme {
padding: "20".into(),
}),
Switch {
enabled: *enabled.read(),
ontoggled: move |_| {
enabled.toggle();
rect {
width: "fill",
height: "fill",
main_align: "center",
cross_align: "center",
spacing: "20",
Switch {
enabled: *enabled.read(),
ontoggled: move |_| {
enabled.toggle();
}
}
label {
"Is enabled? {is_enabled}"
}
TheOtherSwitch { }
}
label {
"Is enabled? {is_enabled}"
}
TheOtherSwitch { }
}
)
}

0 comments on commit fe39475

Please sign in to comment.