perspective_viewer/components/column_selector/
empty_column.rs1use std::collections::HashSet;
14
15use perspective_client::config::Expression;
16use web_sys::*;
17use yew::prelude::*;
18
19use crate::components::column_dropdown::ColumnDropDownElement;
20
21#[derive(Properties)]
22pub struct EmptyColumnProps {
23 pub column_dropdown: ColumnDropDownElement,
25
26 pub exclude: HashSet<String>,
28
29 pub on_select: Callback<InPlaceColumn>,
31}
32
33impl PartialEq for EmptyColumnProps {
34 fn eq(&self, _other: &Self) -> bool {
35 false
36 }
37}
38
39#[derive(Clone, Debug, PartialEq)]
40pub enum InPlaceColumn {
41 Column(String),
42 Expression(Expression<'static>),
43}
44
45pub enum EmptyColumnMsg {
46 KeyDown(u32),
47 Blur,
48 Input,
49}
50
51use EmptyColumnMsg::*;
52
53#[derive(Default)]
54pub struct EmptyColumn {
55 input_ref: NodeRef,
56}
57
58impl Component for EmptyColumn {
59 type Message = EmptyColumnMsg;
60 type Properties = EmptyColumnProps;
61
62 fn view(&self, ctx: &Context<Self>) -> Html {
63 let onblur = ctx.link().callback(|_| Blur);
64 let oninput = ctx.link().callback(|_| Input);
65 let onkeydown = ctx
66 .link()
67 .callback(|event: KeyboardEvent| KeyDown(event.key_code()));
68
69 html! {
70 <div class="pivot-column column-empty">
71 <input
72 spellcheck="false"
73 ref={self.input_ref.clone()}
74 {onblur}
75 {onkeydown}
76 {oninput}
77 class="column-empty-input"
78 />
79 </div>
80 }
81 }
82
83 fn changed(&mut self, _ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
84 if let Some(elem) = self.input_ref.cast::<HtmlInputElement>() {
85 elem.blur().unwrap();
86 }
87
88 false
89 }
90
91 fn destroy(&mut self, ctx: &Context<Self>) {
92 ctx.props().column_dropdown.hide().unwrap();
93 }
94
95 fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
96 match msg {
97 Blur => {
98 ctx.props().column_dropdown.hide().unwrap();
99 if let Some(elem) = self.input_ref.cast::<HtmlInputElement>() {
100 elem.set_value("");
101 }
102
103 false
104 },
105 KeyDown(40) => {
106 ctx.props().column_dropdown.item_down();
107 false
108 },
109 KeyDown(38) => {
110 ctx.props().column_dropdown.item_up();
111 false
112 },
113 KeyDown(13) => {
114 ctx.props().column_dropdown.item_select();
115 ctx.props().column_dropdown.hide().unwrap();
116 false
117 },
118 KeyDown(_) => false,
119 Input => {
120 if let Some(elem) = self.input_ref.cast::<HtmlInputElement>() {
121 ctx.props().column_dropdown.autocomplete(
122 elem,
123 ctx.props().exclude.clone(),
124 ctx.props().on_select.clone(),
125 );
126 }
127
128 false
129 },
130 }
131 }
132
133 fn create(_ctx: &Context<Self>) -> Self {
134 Self::default()
135 }
136}