yew_bs/components/
tooltips.rs1use yew::prelude::*;
2use web_sys::Element;
3use wasm_bindgen::JsValue;
4use crate::interop::BsTooltip;
5#[derive(Clone, Copy, PartialEq, Debug)]
6pub enum TooltipPlacement {
7 Auto,
8 Top,
9 Bottom,
10 Left,
11 Right,
12}
13impl TooltipPlacement {
14 pub fn as_str(&self) -> &'static str {
15 match self {
16 TooltipPlacement::Auto => "auto",
17 TooltipPlacement::Top => "top",
18 TooltipPlacement::Bottom => "bottom",
19 TooltipPlacement::Left => "left",
20 TooltipPlacement::Right => "right",
21 }
22 }
23}
24#[derive(Clone, Copy, PartialEq, Debug)]
26pub enum TooltipTrigger {
27 Hover,
28 Focus,
29 Click,
30 Manual,
31}
32impl TooltipTrigger {
33 pub fn as_str(&self) -> &'static str {
34 match self {
35 TooltipTrigger::Hover => "hover",
36 TooltipTrigger::Focus => "focus",
37 TooltipTrigger::Click => "click",
38 TooltipTrigger::Manual => "manual",
39 }
40 }
41}
42#[derive(Properties, PartialEq)]
43pub struct TooltipProps {
44 #[prop_or_default]
45 pub children: Children,
46 pub title: AttrValue,
47 #[prop_or(TooltipPlacement::Top)]
48 pub placement: TooltipPlacement,
49 #[prop_or(TooltipTrigger::Hover)]
50 pub trigger: TooltipTrigger,
51 #[prop_or_default]
52 pub show: bool,
53 #[prop_or_default]
54 pub class: Option<AttrValue>,
55 #[prop_or_default]
56 pub node_ref: NodeRef,
57}
58#[function_component(Tooltip)]
59pub fn tooltip(props: &TooltipProps) -> Html {
60 let node_ref = props.node_ref.clone();
61 let options = {
62 let opts = js_sys::Object::new();
63 js_sys::Reflect::set(
64 &opts,
65 &"title".into(),
66 &JsValue::from(props.title.as_str()),
67 )
68 .unwrap();
69 js_sys::Reflect::set(
70 &opts,
71 &"placement".into(),
72 &JsValue::from(props.placement.as_str()),
73 )
74 .unwrap();
75 js_sys::Reflect::set(
76 &opts,
77 &"trigger".into(),
78 &JsValue::from(props.trigger.as_str()),
79 )
80 .unwrap();
81 JsValue::from(opts)
82 };
83 {
84 let node_ref = node_ref.clone();
85 let trigger = props.trigger;
86 use_effect_with(
87 (options.clone(), props.show),
88 move |(options, show)| {
89 if let Some(element) = node_ref.cast::<Element>() {
90 let bs_tooltip = BsTooltip::new(&element, Some(&options));
91 match trigger {
92 TooltipTrigger::Manual => {
93 if *show {
94 bs_tooltip.show();
95 } else {
96 bs_tooltip.hide();
97 }
98 }
99 _ => {}
100 }
101 }
102 || ()
103 },
104 );
105 }
106 let children = props.children.clone();
107 html! {
108 < span ref = { props.node_ref.clone() } data - bs - toggle = "tooltip" data - bs
109 - title = { props.title.clone() } data - bs - placement = { props.placement
110 .as_str() } data - bs - trigger = { props.trigger.as_str() } class = { props
111 .class.clone() } > { for children.iter() } </ span >
112 }
113}