use freya_core::prelude::*;
use freya_router::prelude::{
NavigationTarget,
Navigator,
};
use crate::{
get_theme,
theming::component_themes::LinkThemePartial,
tooltip::{
Tooltip,
TooltipContainer,
},
};
#[derive(Clone, PartialEq)]
pub enum LinkTooltip {
None,
Default,
Custom(String),
}
#[derive(PartialEq)]
pub struct Link {
pub(crate) theme: Option<LinkThemePartial>,
to: NavigationTarget,
children: Vec<Element>,
tooltip: LinkTooltip,
}
impl ChildrenExt for Link {
fn get_children(&mut self) -> &mut Vec<Element> {
&mut self.children
}
}
impl Link {
pub fn new(to: impl Into<NavigationTarget>) -> Self {
Self {
to: to.into(),
children: Vec::new(),
tooltip: LinkTooltip::Default,
theme: None,
}
}
pub fn tooltip(mut self, tooltip: impl Into<LinkTooltip>) -> Self {
self.tooltip = tooltip.into();
self
}
}
impl Render for Link {
fn render(&self) -> impl IntoElement {
let theme = get_theme!(&self.theme, link);
let mut is_hovering = use_state(|| false);
let url = if let NavigationTarget::External(ref url) = self.to {
Some(url.clone())
} else {
None
};
let on_pointer_enter = move |_| {
is_hovering.set(true);
};
let on_pointer_leave = move |_| {
is_hovering.set(false);
};
let on_press = {
let to = self.to.clone();
let url = url.clone();
move |_| {
if let Some(url) = &url {
let _ = open::that(url);
} else {
Navigator::get().push(to.clone());
}
}
};
let color = if *is_hovering.read() {
Some(theme.color)
} else {
None
};
let tooltip_text = match &self.tooltip {
LinkTooltip::Default => url.clone(),
LinkTooltip::None => None,
LinkTooltip::Custom(str) => Some(str.clone()),
};
let link = rect()
.on_press(on_press)
.on_pointer_enter(on_pointer_enter)
.on_pointer_leave(on_pointer_leave)
.map(color, |rect, color| rect.color(color))
.children(self.children.clone());
if let Some(tooltip_text) = tooltip_text {
TooltipContainer::new(Tooltip::new(tooltip_text))
.child(link)
.into_element()
} else {
link.into()
}
}
}