use crate::styles::{get_palette, get_size, get_style, Palette, Position, Size, Style};
use stylist::{css, StyleSource};
use wasm_bindgen_test::*;
use yew::prelude::*;
use yew::{utils, App};
pub struct Tooltip {
props: Props,
link: ComponentLink<Self>,
show_tooltip: bool,
}
#[derive(Clone, Properties, PartialEq)]
pub struct Props {
#[prop_or(Palette::Standard)]
pub tooltip_palette: Palette,
#[prop_or(Style::Regular)]
pub tooltip_style: Style,
#[prop_or(Size::Medium)]
pub tooltip_size: Size,
#[prop_or_default]
pub key: String,
#[prop_or_default]
pub code_ref: NodeRef,
#[prop_or_default]
pub class_name: String,
#[prop_or_default]
pub id: String,
pub tooltip_position: Position,
pub content: Html,
#[prop_or(css!(""))]
pub styles: StyleSource<'static>,
pub children: Children,
}
pub enum Msg {
TargetOver,
TargetLeave,
}
impl Component for Tooltip {
type Message = Msg;
type Properties = Props;
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {
props,
link,
show_tooltip: false,
}
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::TargetOver => self.show_tooltip = true,
Msg::TargetLeave => self.show_tooltip = false,
};
true
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props {
self.props = props;
return true;
}
false
}
fn view(&self) -> Html {
let tooltip = html! {
<div
id=self.props.id.clone()
key=self.props.key.clone()
ref=self.props.code_ref.clone()
class=classes!(
"tooltip",
get_position(self.props.tooltip_position.clone()),
get_palette(self.props.tooltip_palette.clone()),
get_style(self.props.tooltip_style.clone()),
get_size(self.props.tooltip_size.clone()),
self.props.class_name.clone(),
self.props.styles.clone()
)
>
{self.props.content.clone()}
</div>
};
html! {
<div class="tooltip-container"
onmouseover = self.link.callback(|_| Msg::TargetOver)
onmouseleave = self.link.callback(|_| Msg::TargetLeave)
>
{if self.show_tooltip {
tooltip
}else {
html!{}
}}
{self.props.children.clone()}
</div>
}
}
}
fn get_position(position: Position) -> String {
match position {
Position::Left => String::from("left"),
Position::Right => String::from("right"),
Position::Above => String::from("above"),
Position::Below => String::from("below"),
}
}
#[wasm_bindgen_test]
fn should_create_tooltip() {
let tooltip_props = Props {
tooltip_palette: Palette::Clean,
tooltip_style: Style::Regular,
tooltip_size: Size::Medium,
tooltip_position: Position::Above,
content: html! {<p>{"tooltip"}</p>},
code_ref: NodeRef::default(),
key: String::from("dropdown-1"),
class_name: String::from("class-test"),
id: String::from("id-test"),
styles: css!("color: blue;"),
children: Children::new(vec![html! {<div id="result">{"result"}</div>}]),
};
let tooltip: App<Tooltip> = App::new();
tooltip.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
tooltip_props,
);
let tooltip_element = utils::document()
.get_elements_by_class_name("tooltip-container")
.get_with_index(0)
.unwrap();
let child = tooltip_element.first_element_child().unwrap();
assert_eq!(child.id(), "result".to_string());
}