Skip to content

Commit e490129

Browse files
committed
Auto-complete text field column selectors
1 parent 379cb38 commit e490129

29 files changed

+988
-180
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/******************************************************************************
2+
*
3+
* Copyright (c) 2017, the Perspective Authors.
4+
*
5+
* This file is part of the Perspective library, distributed under the terms of
6+
* the Apache License 2.0. The full license can be found in the LICENSE file.
7+
*
8+
*/
9+
10+
@mixin icon {
11+
background-repeat: no-repeat;
12+
background-color: var(--icon--color);
13+
content: "";
14+
display: inline-block;
15+
-webkit-mask-size: cover;
16+
mask-size: cover;
17+
}
18+
19+
:host {
20+
box-sizing: border-box;
21+
position: fixed;
22+
z-index: 10000;
23+
outline: none;
24+
font-size: 12px;
25+
border: inherit;
26+
// box-shadow: 0 2px 4px 0 rgb(0 0 0 / 10%);
27+
user-select: none;
28+
background-color: var(--icon--color, #fff) !important;
29+
color: var(--plugin--background, #333) !important;
30+
// padding: 6px 8px;
31+
border: 1px solid var(--icon--color) !important;
32+
max-width: 300px;
33+
overflow: hidden;
34+
max-height: 600px;
35+
overflow: scroll;
36+
37+
display: flex;
38+
flex-direction: column;
39+
40+
.selected {
41+
background-color: var(--plugin--background) !important;
42+
color: var(--icon--color) !important;
43+
}
44+
45+
span {
46+
cursor: pointer;
47+
padding: 4px 5px;
48+
}
49+
50+
.no-results {
51+
padding: 3px 24px 6px 11px;
52+
color: var(--error--color);
53+
font-size: 8px;
54+
}
55+
56+
#add-expression {
57+
&:before {
58+
@include icon;
59+
width: 14px;
60+
height: 12px;
61+
margin-right: 5px;
62+
-webkit-mask-image: var(--add-expression-icon--mask-image);
63+
mask-image: var(--add-expression-icon--mask-image);
64+
}
65+
}
66+
}
67+
68+
:host(:hover) {
69+
.selected {
70+
background-color: var(--icon--color, #fff) !important;
71+
color: var(--plugin--background, #333) !important;
72+
}
73+
74+
span:hover,
75+
span.selected:hover {
76+
background-color: var(--plugin--background) !important;
77+
color: var(--icon--color) !important;
78+
}
79+
}
80+
81+
:host(.no-results) {
82+
background-color:transparent!important;
83+
border:none!important;
84+
}

rust/perspective-viewer/src/less/config-selector.less

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
}
8282

8383
.input-sizer {
84-
flex: 1 1 auto;
84+
flex: 1 100000 auto;
8585
}
8686
}
8787

@@ -99,10 +99,6 @@
9999
cursor: move;
100100
}
101101

102-
&.column-empty .pivot-column-draggable {
103-
cursor: auto;
104-
}
105-
106102
&:not(.column-empty) .pivot-column-border:before {
107103
flex: 0 0 auto;
108104
height: 12px;
@@ -128,15 +124,6 @@
128124
overflow: hidden;
129125
}
130126

131-
&.column-empty .pivot-column-draggable {
132-
background-color: #8b868045;
133-
border: 1px solid transparent;
134-
padding-bottom: 0px;
135-
margin-bottom: 4px;
136-
min-height: 24px;
137-
width: calc(100% - 7px);
138-
}
139-
140127
// Column is being dragged-over, e.g. this is the drop indicator.
141128
& .config-drop {
142129
background-color: #8b868045;
@@ -287,16 +274,21 @@
287274

288275
#transpose_button {
289276
cursor: pointer;
290-
min-width: 5px;
291-
max-width: 5px;
292277
flex-grow: 0;
293-
font-family: Arial;
294-
font-size: 12px;
278+
font-family: inherit;
279+
font-size: 9px;
295280
user-select: none;
296-
padding: 12px 24px 0 0;
281+
padding: 0;
282+
align-self: center;
283+
margin-bottom: -23px;
284+
margin-top: 11.5px;
285+
align-self: flex-end;
286+
z-index: 1;
287+
min-height: 0px;
288+
margin-right: 30px;
297289

298290
&:hover:before {
299-
color: var(--active--color, inherit);
291+
color: var(--icon--color, inherit);
300292
}
301293

302294
&:before {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
:host {
2+
.column-empty {
3+
width: 100%;
4+
}
5+
6+
.column-empty-input {
7+
position: relative;
8+
width: calc(100% - 27px);
9+
min-height: 28px;
10+
display: flex;
11+
align-items: stretch;
12+
cursor: auto;
13+
14+
background-color: #8b868045;
15+
border: 1px solid transparent;
16+
border-radius: 2px;
17+
padding-bottom: 0px;
18+
margin-bottom: 4px;
19+
min-height: 24px;
20+
width: calc(100% - 7px);
21+
outline: none;
22+
padding-left: 10px;
23+
font-size: 12px;
24+
font-family: inherit;
25+
}
26+
27+
.column-empty-input:focus {
28+
color: var(--plugin--background);
29+
background-color: var(--icon--color);
30+
border: 1px solid var(--icon--color);
31+
}
32+
}

rust/perspective-viewer/src/less/filter-item.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
font-size: 12px;
2323
min-width: 45px;
2424
overflow: hidden;
25+
height: 16px;
2526

2627
&:after,
2728
input,

rust/perspective-viewer/src/less/render-warning.less

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
z-index: 10000;
2323
user-select: none;
2424
left: 48px;
25-
right: 48px;
2625
padding-left: 24px;
2726
padding-right: 24px;
2827
border-radius: 24px;
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2018, the Perspective Authors.
4+
//
5+
// This file is part of the Perspective library, distributed under the terms
6+
// of the Apache License 2.0. The full license can be found in the LICENSE
7+
// file.
8+
9+
use web_sys::*;
10+
use yew::prelude::*;
11+
12+
use super::modal::*;
13+
use super::InPlaceColumn;
14+
use crate::utils::WeakScope;
15+
use crate::*;
16+
17+
static CSS: &str = include_str!("../../../target/css/column-dropdown.css");
18+
19+
pub enum ColumnDropDownMsg {
20+
SetValues(Vec<InPlaceColumn>, f64),
21+
SetCallback(Callback<InPlaceColumn>),
22+
ItemDown,
23+
ItemUp,
24+
ItemSelect,
25+
}
26+
27+
pub struct ColumnDropDown {
28+
values: Option<Vec<InPlaceColumn>>,
29+
selected: usize,
30+
width: f64,
31+
on_select: Option<Callback<InPlaceColumn>>,
32+
}
33+
34+
#[derive(Properties, PartialEq)]
35+
pub struct ColumnDropDownProps {
36+
#[prop_or_default]
37+
pub weak_link: WeakScope<ColumnDropDown>,
38+
}
39+
40+
impl ModalLink<ColumnDropDown> for ColumnDropDownProps {
41+
fn weak_link(&self) -> &'_ WeakScope<ColumnDropDown> {
42+
&self.weak_link
43+
}
44+
}
45+
46+
impl Component for ColumnDropDown {
47+
type Message = ColumnDropDownMsg;
48+
type Properties = ColumnDropDownProps;
49+
50+
fn create(ctx: &Context<Self>) -> Self {
51+
ctx.set_modal_link();
52+
Self {
53+
values: Some(vec![]),
54+
selected: 0,
55+
width: 0.0,
56+
on_select: None,
57+
}
58+
}
59+
60+
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
61+
match msg {
62+
ColumnDropDownMsg::SetCallback(callback) => {
63+
self.on_select = Some(callback);
64+
false
65+
}
66+
ColumnDropDownMsg::SetValues(values, width) => {
67+
self.values = Some(values);
68+
self.selected = 0;
69+
self.width = width;
70+
true
71+
}
72+
ColumnDropDownMsg::ItemSelect => {
73+
if let Some(ref values) = self.values {
74+
match values.get(self.selected) {
75+
None => {
76+
console::error_1(&"Selected out-of-bounds".into());
77+
false
78+
}
79+
Some(x) => {
80+
self.on_select.as_ref().unwrap().emit(x.clone());
81+
false
82+
}
83+
}
84+
} else {
85+
console::error_1(&"No Values".into());
86+
false
87+
}
88+
}
89+
ColumnDropDownMsg::ItemDown => {
90+
self.selected += 1;
91+
if let Some(ref values) = self.values {
92+
if self.selected >= values.len() {
93+
self.selected = 0;
94+
};
95+
};
96+
97+
true
98+
}
99+
ColumnDropDownMsg::ItemUp => {
100+
if let Some(ref values) = self.values {
101+
if self.selected < 1 {
102+
self.selected = values.len();
103+
}
104+
}
105+
106+
self.selected -= 1;
107+
true
108+
}
109+
}
110+
}
111+
112+
fn changed(&mut self, _ctx: &Context<Self>, _old: &Self::Properties) -> bool {
113+
false
114+
}
115+
116+
fn view(&self, _ctx: &Context<Self>) -> Html {
117+
let body = html! {
118+
if let Some(ref values) = self.values {
119+
if !values.is_empty() {
120+
{
121+
for values
122+
.iter()
123+
.enumerate()
124+
.map(|(idx, value)| {
125+
let click = self.on_select.as_ref().unwrap().reform({
126+
let value = value.clone();
127+
move |_: MouseEvent| value.clone()
128+
});
129+
130+
let row = match value {
131+
InPlaceColumn::Column(col) => html! {
132+
<span>{ col }</span>
133+
},
134+
InPlaceColumn::Expression(col) => html! {
135+
<span id="add-expression">{ col }</span>
136+
},
137+
};
138+
139+
html! {
140+
if idx == self.selected {
141+
<span onmousedown={ click } class="selected">{ row }</span>
142+
} else {
143+
<span onmousedown={ click }>{ row }</span>
144+
}
145+
}
146+
})
147+
}
148+
} else {
149+
<span class="no-results">{ "Invalid Column" }</span>
150+
}
151+
}
152+
};
153+
154+
let position = format!(
155+
":host{{min-width:{}px;max-width:{}px}}",
156+
self.width, self.width
157+
);
158+
159+
html_template! {
160+
<style>
161+
{ &CSS }
162+
</style>
163+
<style>
164+
{ position }
165+
</style>
166+
{ body }
167+
}
168+
}
169+
}

0 commit comments

Comments
 (0)