use crate::styles::{get_palette, get_size, get_style, Palette, Size, Style};
use wasm_bindgen_test::*;
use yew::prelude::*;
use yew::{utils, App};
use yew_assets::editing_assets::{EditingAssets, EditingIcon};
pub struct Text {
link: ComponentLink<Self>,
props: Props,
}
#[derive(Clone, PartialEq)]
pub enum Header {
H1,
H2,
H3,
H4,
H5,
H6,
}
#[derive(Clone, PartialEq)]
pub enum TextType {
Title(Header),
Plain,
Paragraph,
Alert,
Tag,
}
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
pub text_type: TextType,
#[prop_or_default]
pub plain_text: String,
pub html_text: Option<Html>,
#[prop_or(false)]
pub interaction_effect: bool,
#[prop_or(Callback::noop())]
pub ondrag_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragend_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragenter_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragexit_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragleave_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragover_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondragstart_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub ondrop_signal: Callback<DragEvent>,
#[prop_or(Callback::noop())]
pub onclick_signal: Callback<MouseEvent>,
#[prop_or(Callback::noop())]
pub ondelete_signal: Callback<MouseEvent>,
#[prop_or(false)]
pub draggable: bool,
#[prop_or(false)]
pub removable: bool,
#[prop_or(Palette::Standard)]
pub text_palette: Palette,
#[prop_or(Style::Regular)]
pub text_style: Style,
#[prop_or(Size::Medium)]
pub text_size: Size,
#[prop_or_default]
pub code_ref: NodeRef,
#[prop_or_default]
pub key: String,
#[prop_or_default]
pub class_name: String,
#[prop_or_default]
pub id: String,
}
pub enum Msg {
Draged(DragEvent),
DragedEnd(DragEvent),
DragedEnter(DragEvent),
DragedExit(DragEvent),
DragedLeave(DragEvent),
DragedOver(DragEvent),
DragedStart(DragEvent),
Dropped(DragEvent),
Clicked(MouseEvent),
Deleted(MouseEvent),
}
impl Component for Text {
type Message = Msg;
type Properties = Props;
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { link, props }
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::Draged(drag_event) => {
self.props.ondrag_signal.emit(drag_event);
}
Msg::DragedEnd(drag_event) => {
self.props.ondragend_signal.emit(drag_event);
}
Msg::DragedEnter(drag_event) => {
self.props.ondragenter_signal.emit(drag_event);
}
Msg::DragedExit(drag_event) => {
self.props.ondragexit_signal.emit(drag_event);
}
Msg::DragedLeave(drag_event) => {
self.props.ondragleave_signal.emit(drag_event);
}
Msg::DragedOver(drag_event) => {
self.props.ondragover_signal.emit(drag_event);
}
Msg::DragedStart(drag_event) => {
self.props.ondragstart_signal.emit(drag_event);
}
Msg::Dropped(drag_event) => {
self.props.ondrop_signal.emit(drag_event);
}
Msg::Clicked(mouse_event) => self.props.onclick_signal.emit(mouse_event),
Msg::Deleted(mouse_event) => self.props.ondelete_signal.emit(mouse_event),
}
true
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
fn view(&self) -> Html {
get_text(
self.props.text_type.clone(),
self.props.clone(),
self.link.clone(),
)
}
}
fn get_content(plain_text: String, html_text: Option<Html>) -> Html {
if !plain_text.is_empty() {
html! { <>{plain_text}</> }
} else if let Some(html_text_value) = html_text {
html_text_value
} else {
panic!("One of the props plain_text or html_text should be something");
}
}
fn get_text(text_type: TextType, props: Props, link: ComponentLink<Text>) -> Html {
match text_type {
TextType::Title(header) => get_header(header, props),
TextType::Plain => {
html! {
<span
class=format!("plain-text {} {}", get_size(props.text_size), props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</span>
}
}
TextType::Paragraph => {
html! {
<p
class=format!("paragraph-text {} {}", get_size(props.text_size), props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</p>
}
}
TextType::Alert => {
html! {
<div
class=format!(
"alert-text {} {} {} {}",
get_style(props.text_style),
get_palette(props.text_palette),
get_size(props.text_size),
props.class_name,
)
id =props.id
key=props.key
ref=props.code_ref
>
<span>{get_content(props.plain_text, props.html_text)}</span>
</div>
}
}
TextType::Tag => {
html! {
<div
class=format!(
"tag-text {} {} {} {} {}",
if props.interaction_effect {
"interaction"
} else {
""
},
get_style(props.text_style),
get_palette(props.text_palette),
get_size(props.text_size.clone()),
props.class_name,
)
id =props.id
key=props.key
ref=props.code_ref
draggable = props.draggable
ondrag = link.callback(Msg::Draged)
ondragend = link.callback(Msg::DragedEnd)
ondragenter = link.callback(Msg::DragedEnter)
ondragexit = link.callback(Msg::DragedExit)
ondragleave = link.callback(Msg::DragedLeave)
ondragover = link.callback(Msg::DragedOver)
ondragstart = link.callback(Msg::DragedStart)
ondrop = link.callback(Msg::Dropped)
onclick = link.callback(Msg::Clicked)
>
<span>{get_content(props.plain_text, props.html_text)}</span>
{if props.removable {
html!{
<div
class="tag-delete"
onclick= link.callback(Msg::Deleted)
>
<EditingAssets
icon=EditingIcon::X
size=if props.text_size == Size::Medium {
("20".to_string(), "20".to_string())
} else if props.text_size == Size::Small {
("13".to_string(), "13".to_string())
} else {
("24".to_string(), "24".to_string())
}
/>
</div>
}
} else {
html!{}
}}
</div>
}
}
}
}
fn get_header(header: Header, props: Props) -> Html {
match header {
Header::H1 => html! {<h1
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h1>},
Header::H2 => html! {<h2
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h2>},
Header::H3 => html! {<h3
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h3>},
Header::H4 => html! {<h4
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h4>},
Header::H5 => html! {<h5
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h5>},
Header::H6 => html! {<h6
class=format!("header-text {}", props.class_name)
id=props.id
key=props.key
ref=props.code_ref
>{get_content(props.plain_text, props.html_text)}</h6>},
}
}
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn should_create_plain_text() {
let props = Props {
text_type: TextType::Plain,
ondrag_signal: Callback::noop(),
ondragend_signal: Callback::noop(),
ondragenter_signal: Callback::noop(),
ondragexit_signal: Callback::noop(),
ondragleave_signal: Callback::noop(),
ondragover_signal: Callback::noop(),
ondragstart_signal: Callback::noop(),
ondrop_signal: Callback::noop(),
onclick_signal: Callback::noop(),
ondelete_signal: Callback::noop(),
draggable: false,
removable: false,
plain_text: "hello test".to_string(),
html_text: None,
text_palette: Palette::Primary,
text_style: Style::Regular,
text_size: Size::Medium,
interaction_effect: false,
key: "".to_string(),
code_ref: NodeRef::default(),
class_name: "class-card-test".to_string(),
id: "id-text-test".to_string(),
};
let text: App<Text> = App::new();
text.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
props,
);
let plain_text_element = utils::document()
.get_elements_by_class_name("plain-text")
.get_with_index(0);
assert_eq!(plain_text_element.is_some(), true);
}
#[wasm_bindgen_test]
fn should_create_paragraph_text() {
let props = Props {
text_type: TextType::Paragraph,
ondrag_signal: Callback::noop(),
ondragend_signal: Callback::noop(),
ondragenter_signal: Callback::noop(),
ondragexit_signal: Callback::noop(),
ondragleave_signal: Callback::noop(),
ondragover_signal: Callback::noop(),
ondragstart_signal: Callback::noop(),
ondrop_signal: Callback::noop(),
onclick_signal: Callback::noop(),
ondelete_signal: Callback::noop(),
draggable: false,
removable: false,
plain_text: "hello test".to_string(),
html_text: None,
text_palette: Palette::Primary,
text_style: Style::Regular,
text_size: Size::Medium,
interaction_effect: false,
key: "".to_string(),
code_ref: NodeRef::default(),
class_name: "class-card-test".to_string(),
id: "id-text-test".to_string(),
};
let text: App<Text> = App::new();
text.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
props,
);
let paragraph_text_element = utils::document()
.get_elements_by_class_name("paragraph-text")
.get_with_index(0);
assert_eq!(paragraph_text_element.is_some(), true);
}
#[wasm_bindgen_test]
fn should_create_alert_text() {
let props = Props {
text_type: TextType::Alert,
ondrag_signal: Callback::noop(),
ondragend_signal: Callback::noop(),
ondragenter_signal: Callback::noop(),
ondragexit_signal: Callback::noop(),
ondragleave_signal: Callback::noop(),
ondragover_signal: Callback::noop(),
ondragstart_signal: Callback::noop(),
ondrop_signal: Callback::noop(),
onclick_signal: Callback::noop(),
ondelete_signal: Callback::noop(),
draggable: false,
removable: false,
plain_text: "hello test".to_string(),
html_text: None,
text_palette: Palette::Primary,
text_style: Style::Regular,
text_size: Size::Medium,
interaction_effect: false,
key: "".to_string(),
code_ref: NodeRef::default(),
class_name: "class-card-test".to_string(),
id: "id-text-test".to_string(),
};
let text: App<Text> = App::new();
text.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
props,
);
let alert_text_element = utils::document()
.get_elements_by_class_name("alert-text")
.get_with_index(0);
assert_eq!(alert_text_element.is_some(), true);
}
#[wasm_bindgen_test]
fn should_create_tag_text() {
let props = Props {
text_type: TextType::Tag,
ondrag_signal: Callback::noop(),
ondragend_signal: Callback::noop(),
ondragenter_signal: Callback::noop(),
ondragexit_signal: Callback::noop(),
ondragleave_signal: Callback::noop(),
ondragover_signal: Callback::noop(),
ondragstart_signal: Callback::noop(),
ondrop_signal: Callback::noop(),
onclick_signal: Callback::noop(),
ondelete_signal: Callback::noop(),
draggable: false,
removable: false,
plain_text: "hello test".to_string(),
html_text: None,
text_palette: Palette::Primary,
text_style: Style::Regular,
text_size: Size::Medium,
interaction_effect: false,
key: "".to_string(),
code_ref: NodeRef::default(),
class_name: "class-card-test".to_string(),
id: "id-text-test".to_string(),
};
let text: App<Text> = App::new();
text.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
props,
);
let tag_text_element = utils::document()
.get_elements_by_class_name("tag-text")
.get_with_index(0);
assert_eq!(tag_text_element.is_some(), true);
}
#[wasm_bindgen_test]
fn should_add_delete_icon_tag_text() {
let props = Props {
text_type: TextType::Tag,
ondrag_signal: Callback::noop(),
ondragend_signal: Callback::noop(),
ondragenter_signal: Callback::noop(),
ondragexit_signal: Callback::noop(),
ondragleave_signal: Callback::noop(),
ondragover_signal: Callback::noop(),
ondragstart_signal: Callback::noop(),
ondrop_signal: Callback::noop(),
onclick_signal: Callback::noop(),
ondelete_signal: Callback::noop(),
draggable: false,
removable: true,
plain_text: "hello test".to_string(),
html_text: None,
text_palette: Palette::Primary,
text_style: Style::Regular,
text_size: Size::Medium,
interaction_effect: false,
key: "".to_string(),
code_ref: NodeRef::default(),
class_name: "class-card-test".to_string(),
id: "id-text-test".to_string(),
};
let text: App<Text> = App::new();
text.mount_with_props(
utils::document().get_element_by_id("output").unwrap(),
props,
);
let tag_text_element = utils::document()
.get_elements_by_class_name("tag-delete")
.get_with_index(0);
assert_eq!(tag_text_element.is_some(), true);
}