1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
use web_sys::{HtmlInputElement, InputEvent};
use yew::{function_component, html, Callback, Properties, TargetCast};
use crate::components::form::optional_field::OptionalField;
#[derive(Properties, Debug, PartialEq, Clone)]
pub struct NumberFieldProps {
pub label: String,
pub current_value: Option<f64>,
pub default: f64,
pub on_change: Callback<Option<f64>>,
#[prop_or_default]
pub disabled: bool,
#[prop_or_default]
pub min: Option<f64>,
#[prop_or_default]
pub max: Option<f64>,
#[prop_or_default]
pub step: Option<f64>,
}
#[function_component(NumberField)]
pub fn number_field(props: &NumberFieldProps) -> yew::Html {
let parse_number_input = |event: InputEvent| {
Some(
event
.target_unchecked_into::<HtmlInputElement>()
.value_as_number(),
)
};
let number_input = html! {
<input
type="number"
class="parameter"
min={props.min.map(|val| val.to_string())}
max={props.max.map(|val| val.to_string())}
step={props.step.map(|val| val.to_string())}
value={props.current_value.unwrap_or(props.default).to_string()}
oninput={props.on_change.reform(parse_number_input)}
/>
};
html! {
<div class="row">
<OptionalField
label={props.label.clone()}
on_check={props.on_change.reform(|_| None)}
checked={props.current_value.map(|val| val != props.default).unwrap_or_default()}
disabled={props.disabled}
>
{ number_input }
</OptionalField>
</div>
}
}