freya_components/
tooltip.rs1use dioxus::prelude::*;
2use freya_elements::{
3 self as dioxus_elements,
4 events::MouseEvent,
5};
6use freya_hooks::{
7 use_applied_theme,
8 use_node_signal,
9 TooltipTheme,
10 TooltipThemeWith,
11};
12
13#[derive(Props, Clone, PartialEq)]
15pub struct TooltipProps {
16 pub theme: Option<TooltipThemeWith>,
18 pub text: String,
20}
21
22#[cfg_attr(feature = "docs",
61 doc = embed_doc_image::embed_image!("tooltip", "images/gallery_tooltip.png")
62)]
63#[allow(non_snake_case)]
64pub fn Tooltip(TooltipProps { text, theme }: TooltipProps) -> Element {
65 let theme = use_applied_theme!(&theme, tooltip);
66 let TooltipTheme {
67 background,
68 color,
69 border_fill,
70 } = theme;
71
72 rsx!(
73 rect {
74 padding: "4 10",
75 shadow: "0 1 2 1 rgb(0, 0, 0, 0.05)",
76 border: "1 inner {border_fill}",
77 corner_radius: "8",
78 background: "{background}",
79 label { max_lines: "1", font_size: "14", color: "{color}", "{text}" }
80 }
81 )
82}
83
84#[derive(PartialEq, Clone, Copy, Debug)]
85pub enum TooltipPosition {
86 Besides,
87 Below,
88}
89
90#[component]
96pub fn TooltipContainer(
97 tooltip: Element,
98 children: Element,
99 #[props(default = TooltipPosition::Below, into)] position: TooltipPosition,
100) -> Element {
101 let mut is_hovering = use_signal(|| false);
102 let (reference, size) = use_node_signal();
103
104 let onmouseenter = move |_: MouseEvent| {
105 is_hovering.set(true);
106 };
107
108 let onmouseleave = move |_: MouseEvent| {
109 is_hovering.set(false);
110 };
111
112 let direction = match position {
113 TooltipPosition::Below => "vertical",
114 TooltipPosition::Besides => "horizontal",
115 };
116
117 rsx!(
118 rect {
119 direction,
120 reference,
121 onmouseenter,
122 onmouseleave,
123 {children},
124 rect {
125 height: "0",
126 width: "0",
127 layer: "-1500",
128 if *is_hovering.read() {
129 match position {
130 TooltipPosition::Below => rsx!(
131 rect {
132 width: "{size.read().area.width()}",
133 cross_align: "center",
134 padding: "5 0 0 0",
135 {tooltip}
136 }
137 ),
138 TooltipPosition::Besides => rsx!(
139 rect {
140 height: "{size.read().area.height()}",
141 main_align: "center",
142 padding: "0 0 0 5",
143 {tooltip}
144 }
145 ),
146 }
147 }
148 }
149 }
150 )
151}