Skip to content

Commit

Permalink
feat: TooltipContainer (#900)
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 authored Sep 28, 2024
1 parent 4e4afaf commit 9c9aae8
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 45 deletions.
37 changes: 16 additions & 21 deletions crates/components/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use freya_hooks::{
};
use winit::event::MouseButton;

use crate::Tooltip;
use crate::{
Tooltip,
TooltipContainer,
};

/// Tooltip configuration for the [`Link`] component.
#[derive(Clone, PartialEq)]
Expand Down Expand Up @@ -159,7 +162,7 @@ pub fn Link(
Some(LinkTooltip::Custom(str)) => Some(str),
};

let main_rect = rsx! {
let link = rsx! {
rect {
onmouseenter,
onmouseleave,
Expand All @@ -169,27 +172,19 @@ pub fn Link(
}
};

let Some(tooltip) = tooltip else {
return rsx!({ main_rect });
};

rsx! {
rect {
{main_rect}
rect {
height: "0",
width: "0",
layer: "-999",
rect {
width: "100v",
if *is_hovering.read() {
Tooltip {
url: tooltip
}
if let Some(tooltip) = tooltip {
rsx!(
TooltipContainer {
tooltip: rsx!(
Tooltip {
text: tooltip
}
}
)
{link}
}
}
)
} else {
link
}
}

Expand Down
89 changes: 81 additions & 8 deletions crates/components/src/tooltip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use dioxus::prelude::*;
use freya_elements::elements as dioxus_elements;
use freya_elements::{
elements as dioxus_elements,
events::MouseEvent,
};
use freya_hooks::{
use_applied_theme,
use_node_signal,
TooltipTheme,
TooltipThemeWith,
};
Expand All @@ -11,16 +15,16 @@ use freya_hooks::{
pub struct TooltipProps {
/// Theme override.
pub theme: Option<TooltipThemeWith>,
/// Url as the Tooltip destination.
pub url: String,
/// Text to show in the [Tooltip].
pub text: String,
}

/// `Tooltip` component
///
/// # Styling
/// Inherits the [`TooltipTheme`](freya_hooks::TooltipTheme)
#[allow(non_snake_case)]
pub fn Tooltip(TooltipProps { url, theme }: TooltipProps) -> Element {
pub fn Tooltip(TooltipProps { text, theme }: TooltipProps) -> Element {
let theme = use_applied_theme!(&theme, tooltip);
let TooltipTheme {
background,
Expand All @@ -31,12 +35,81 @@ pub fn Tooltip(TooltipProps { url, theme }: TooltipProps) -> Element {
rsx!(
rect {
padding: "4 10",
shadow: "0 4 5 0 rgb(0, 0, 0, 0.1)",
shadow: "0 0 4 1 rgb(0, 0, 0, 0.1)",
border: "1 solid {border_fill}",
corner_radius: "10",
corner_radius: "8",
background: "{background}",
main_align: "center",
label { max_lines: "1", color: "{color}", "{url}" }
label { max_lines: "1", font_size: "14", color: "{color}", "{text}" }
}
)
}

#[derive(PartialEq, Clone, Copy, Debug)]
pub enum TooltipPosition {
Besides,
Below,
}

/// `TooltipContainer` component.
///
/// Provides a hoverable area where to show a [Tooltip].
///
/// # Example
#[component]
pub fn TooltipContainer(
tooltip: Element,
children: Element,
#[props(default = TooltipPosition::Below, into)] position: TooltipPosition,
) -> Element {
let mut is_hovering = use_signal(|| false);
let (reference, size) = use_node_signal();

let onmouseenter = move |_: MouseEvent| {
is_hovering.set(true);
};

let onmouseleave = move |_: MouseEvent| {
is_hovering.set(false);
};

let direction = match position {
TooltipPosition::Below => "vertical",
TooltipPosition::Besides => "horizontal",
};

rsx!(
rect {
direction,
reference,
onmouseenter,
onmouseleave,
{children},
if *is_hovering.read() {
rect {
height: "0",
width: "0",
layer: "-999",
match position {
TooltipPosition::Below => rsx!(
rect {
width: "{size.read().area.width()}",
cross_align: "center",
padding: "5 0 0 0",
{tooltip}
}
),
TooltipPosition::Besides => rsx!(
rect {
height: "{size.read().area.height()}",
main_align: "center",
padding: "0 0 0 5",
{tooltip}
}
),
}

}
}
}
)
}
12 changes: 10 additions & 2 deletions crates/core/src/render/skia_measurer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,11 @@ pub fn create_label(
}

let mut paragraph = paragraph_builder.build();
paragraph.layout(area_size.width + 1.0);
paragraph.layout(if font_style.max_lines == Some(1) {
f32::MAX
} else {
area_size.width + 1.0
});

// Measure the actual text height, ignoring the line height
let mut height = paragraph.height();
Expand Down Expand Up @@ -268,7 +272,11 @@ pub fn create_paragraph(
}

let mut paragraph = paragraph_builder.build();
paragraph.layout(area_size.width + 1.0);
paragraph.layout(if font_style.max_lines == Some(1) {
f32::MAX
} else {
area_size.width + 1.0
});

// Measure the actual text height, ignoring the line height
let mut height = paragraph.height();
Expand Down
45 changes: 31 additions & 14 deletions examples/switch_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,41 @@ fn ThemeChanger() -> Element {
let mut theme = use_theme();

rsx!(
Tile {
onselect: move |_| theme.set(DARK_THEME),
leading: rsx!(
Radio {
selected: theme.read().name == "dark",
},
TooltipContainer {
position: TooltipPosition::Besides,
tooltip: rsx!(
Tooltip {
text: "Switch to Dark theme"
}
),
label { "Dark" }
Tile {
onselect: move |_| theme.set(DARK_THEME),
leading: rsx!(
Radio {
selected: theme.read().name == "dark",
},
),
label { "Dark" }
}
}
Tile {
onselect: move |_| theme.set(LIGHT_THEME),
leading: rsx!(
Radio {
selected: theme.read().name == "light",
},
TooltipContainer {
position: TooltipPosition::Besides,
tooltip: rsx!(
Tooltip {
text: "Switch to Light theme"
}
),
label { "Light" }
Tile {
onselect: move |_| theme.set(LIGHT_THEME),
leading: rsx!(
Radio {
selected: theme.read().name == "light",
},
),
label { "Light" }
}
}

)
}

Expand Down
44 changes: 44 additions & 0 deletions examples/tooltip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]

use freya::prelude::*;

fn main() {
launch(app);
}

fn app() -> Element {
rsx!(
rect {
height: "fill",
width: "fill",
main_align: "center",
cross_align: "center",
direction: "horizontal",
spacing: "10",
TooltipContainer {
tooltip: rsx!(
Tooltip {
text: "Hello, World!"
}
),
Button {
label { "Hello!!" }
}
}
TooltipContainer {
position: TooltipPosition::Besides,
tooltip: rsx!(
Tooltip {
text: "Hello, World!"
}
),
Button {
label { "Hello!!" }
}
}
}
)
}

0 comments on commit 9c9aae8

Please sign in to comment.