Fix InputGroup dynamic padding (#124)

* Fix InputGroup dynamic padding

* Yew+clippy=💔
This commit is contained in:
Cecile Tonglet 2021-09-21 10:43:13 +01:00 committed by GitHub
parent a5e7fadf4f
commit bf0a6663cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 27 deletions

View file

@ -6,6 +6,7 @@ pub struct Example {
props: ExampleProps,
histogram_value: String,
password_value: String,
password_strength: Html,
tags_value: String,
}
@ -25,7 +26,7 @@ pub enum Msg {
UpdatePassword(String),
AddTagsEntry,
UpdateTags(String),
Nope,
Noop,
}
macro_rules! alert {
@ -44,9 +45,10 @@ impl Component for Example {
Example {
props,
link,
histogram_value: String::new(),
password_value: String::new(),
tags_value: String::new(),
histogram_value: Default::default(),
password_value: Default::default(),
password_strength: Default::default(),
tags_value: Default::default(),
}
}
@ -54,32 +56,40 @@ impl Component for Example {
match msg {
Msg::AddHistogramEntry => {
alert!("You sent: {}", self.histogram_value);
self.histogram_value = String::new();
self.histogram_value = Default::default();
true
}
Msg::UpdateHistogram(val) => {
self.histogram_value = val;
Msg::UpdateHistogram(value) => {
self.histogram_value = value;
true
}
Msg::AddPasswordEntry => {
alert!("you sent: {}", self.password_value);
self.password_value = String::new();
alert!("You sent: {}", self.password_value);
self.password_value = Default::default();
true
}
Msg::UpdatePassword(val) => {
self.password_value = val;
Msg::UpdatePassword(value) => {
self.password_strength = match value.len() {
n if n == 0 => html!(),
n if n < 4 => html!(<Tag>{"weak"}</Tag>),
n if n < 8 => html!(<Tag>{"medium"}</Tag>),
_ => html!(<Tag>{"strong"}</Tag>),
};
self.password_value = value;
true
}
Msg::AddTagsEntry => {
alert!("You sent: {}", self.tags_value);
self.tags_value = String::new();
self.tags_value = Default::default();
true
}
Msg::UpdateTags(val) => {
self.tags_value = val;
true
}
Msg::Nope => false,
Msg::Noop => false,
}
}
@ -106,7 +116,7 @@ impl Component for Example {
value=self.histogram_value.clone()
oninput=self.link.callback(|e: InputData| Msg::UpdateHistogram(e.value))
onkeydown=self.link.callback(|e: KeyboardEvent| {
if e.key() == "Enter" { Msg::AddHistogramEntry } else { Msg::Nope }
if e.key() == "Enter" { Msg::AddHistogramEntry } else { Msg::Noop }
})
/>
<InputGroup
@ -115,11 +125,12 @@ impl Component for Example {
small=self.props.small
round=self.props.round
disabled=self.props.disabled
left_element=self.password_strength.clone()
placeholder={"Enter your password..."}
value=self.password_value.clone()
oninput=self.link.callback(|e: InputData| Msg::UpdatePassword(e.value))
onkeydown=self.link.callback(|e: KeyboardEvent| {
if e.key() == "Enter" { Msg::AddPasswordEntry } else { Msg::Nope }
if e.key() == "Enter" { Msg::AddPasswordEntry } else { Msg::Noop }
})
right_element=html! {
<Button
@ -140,14 +151,14 @@ impl Component for Example {
value=self.tags_value.clone()
oninput=self.link.callback(|e: InputData| Msg::UpdateTags(e.value))
onkeydown=self.link.callback(|e: KeyboardEvent| {
if e.key() == "Enter" { Msg::AddTagsEntry } else { Msg::Nope }
if e.key() == "Enter" { Msg::AddTagsEntry } else { Msg::Noop }
})
right_element=html! {
<Tag
minimal=true
round=self.props.round
>
{"10000"}
{{10000 / 1.max(self.tags_value.len().pow(2))}}
</Tag>
}
/>

View file

@ -1,8 +1,15 @@
use crate::{Icon, IconName};
use yew::prelude::*;
const MIN_HORIZONTAL_PADDING: i32 = 10;
pub struct InputGroup {
props: InputGroupProps,
link: ComponentLink<Self>,
left_element_ref: NodeRef,
left_element_width: Option<i32>,
right_element_ref: NodeRef,
right_element_width: Option<i32>,
}
#[derive(Copy, Clone, PartialEq, Debug, Hash)]
@ -84,8 +91,15 @@ impl Component for InputGroup {
type Message = ();
type Properties = InputGroupProps;
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self { props }
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {
props,
link,
left_element_ref: Default::default(),
left_element_width: Default::default(),
right_element_ref: Default::default(),
right_element_width: Default::default(),
}
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
@ -102,6 +116,17 @@ impl Component for InputGroup {
}
fn view(&self) -> Html {
let input_style = match (self.left_element_width, self.right_element_width) {
(Some(left), None) => format!("padding-left:{}px", left.max(MIN_HORIZONTAL_PADDING)),
(None, Some(right)) => format!("padding-right:{}px", right.max(MIN_HORIZONTAL_PADDING)),
(Some(left), Some(right)) => format!(
"padding-left:{}px;padding-right:{}px",
left.max(MIN_HORIZONTAL_PADDING),
right.max(MIN_HORIZONTAL_PADDING)
),
_ => Default::default(),
};
html! {
<div
class=classes!(
@ -118,16 +143,14 @@ impl Component for InputGroup {
{
if let Some(left_element) = self.props.left_element.clone() {
html! {
<span class="bp3-input-left-container">
<span
class="bp3-input-left-container"
ref=self.left_element_ref.clone()
>
{left_element}
</span>
}
} else {
html!()
}
}
{
if let Some(icon) = self.props.left_icon {
} else if let Some(icon) = self.props.left_icon {
html! {
<Icon icon=icon />
}
@ -145,11 +168,15 @@ impl Component for InputGroup {
onkeyup={self.props.onkeyup.clone()}
onkeydown={self.props.onkeydown.clone()}
value=self.props.value.clone()
style=input_style
/>
{
if let Some(right_element) = self.props.right_element.clone() {
html! {
<span class="bp3-input-action">
<span
class="bp3-input-action"
ref=self.right_element_ref.clone()
>
{right_element}
</span>
}
@ -160,4 +187,23 @@ impl Component for InputGroup {
</div>
}
}
fn rendered(&mut self, _first_render: bool) {
let left_old_value = self.left_element_width.take();
self.left_element_width = self
.left_element_ref
.cast::<web_sys::Element>()
.map(|x| x.client_width());
let right_old_value = self.right_element_width.take();
self.right_element_width = self
.right_element_ref
.cast::<web_sys::Element>()
.map(|x| x.client_width());
if left_old_value != self.left_element_width || right_old_value != self.right_element_width
{
self.link.send_message(());
}
}
}