lldap/app/src/components/select.rs
Lewis Larsen ba0dc33583
app: front end improvements
Added colour to required asterisks
    Added padding to the footer
    Added bootstrap class to select elements
    Added various icons to buttons
    Fixed various button layouts
    Reworded some messages
    Moved around some form elements

 Fixes #12
2022-11-03 15:40:02 +01:00

114 lines
2.8 KiB
Rust

use yew::{html::ChangeData, prelude::*};
use yewtil::NeqAssign;
pub struct Select {
link: ComponentLink<Self>,
props: SelectProps,
node_ref: NodeRef,
}
#[derive(yew::Properties, Clone, PartialEq, Debug)]
pub struct SelectProps {
pub children: ChildrenWithProps<SelectOption>,
pub on_selection_change: Callback<Option<SelectOptionProps>>,
}
pub enum SelectMsg {
OnSelectChange(ChangeData),
}
impl Select {
fn get_nth_child_props(&self, nth: i32) -> Option<SelectOptionProps> {
if nth == -1 {
return None;
}
self.props
.children
.iter()
.nth(nth as usize)
.map(|child| child.props)
}
fn send_selection_update(&self) {
let select_node = self.node_ref.cast::<web_sys::HtmlSelectElement>().unwrap();
self.props
.on_selection_change
.emit(self.get_nth_child_props(select_node.selected_index()))
}
}
impl Component for Select {
type Message = SelectMsg;
type Properties = SelectProps;
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {
link,
props,
node_ref: NodeRef::default(),
}
}
fn rendered(&mut self, _first_render: bool) {
self.send_selection_update();
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
let SelectMsg::OnSelectChange(data) = msg;
match data {
ChangeData::Select(_) => self.send_selection_update(),
_ => unreachable!(),
}
false
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
self.props.children.neq_assign(props.children)
}
fn view(&self) -> Html {
html! {
<select class="form-select"
ref=self.node_ref.clone()
disabled=self.props.children.is_empty()
onchange=self.link.callback(SelectMsg::OnSelectChange)>
{ self.props.children.clone() }
</select>
}
}
}
pub struct SelectOption {
props: SelectOptionProps,
}
#[derive(yew::Properties, Clone, PartialEq, Eq, Debug)]
pub struct SelectOptionProps {
pub value: String,
pub text: String,
}
impl Component for SelectOption {
type Message = ();
type Properties = SelectOptionProps;
fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
Self { props }
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
false
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
self.props.neq_assign(props)
}
fn view(&self) -> Html {
html! {
<option value=self.props.value.clone()>
{&self.props.text}
</option>
}
}
}