@perspective-dev/viewer 4.5.0 → 4.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/perspective-viewer.js +1 -1
- package/dist/cdn/perspective-viewer.js.map +2 -2
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/phosphor.css +1 -1
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/perspective-viewer.cdn.d.ts +3 -0
- package/dist/esm/perspective-viewer.inline.d.ts +3 -0
- package/dist/esm/perspective-viewer.inline.js +1 -1
- package/dist/esm/perspective-viewer.inline.js.map +2 -2
- package/dist/esm/perspective-viewer.js +1 -1
- package/dist/esm/perspective-viewer.js.map +2 -2
- package/dist/esm/ts-rs/OnUpdateData.d.ts +6 -0
- package/dist/esm/ts-rs/ViewOnUpdateResp.d.ts +4 -0
- package/dist/wasm/perspective-viewer.d.ts +15 -15
- package/dist/wasm/perspective-viewer.js +93 -88
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +15 -15
- package/package.json +1 -1
- package/src/{rust/components/style/local_style.rs → css/_column_dropdown.css} +14 -35
- package/src/css/_dropdown_menu.css +14 -0
- package/src/css/_filter_dropdown.css +14 -0
- package/src/css/_function_dropdown.css +14 -0
- package/src/css/_viewer_bundle.css +41 -0
- package/src/css/column-settings-panel.css +9 -3
- package/src/css/column-style.css +9 -1
- package/src/css/dom/checkbox.css +2 -2
- package/src/css/viewer.css +79 -1
- package/src/rust/components/column_dropdown.rs +3 -3
- package/src/rust/components/column_selector/active_column.rs +3 -0
- package/src/rust/components/column_selector/aggregate_selector.rs +0 -3
- package/src/rust/components/column_selector/config_selector.rs +0 -3
- package/src/rust/components/column_selector/empty_column.rs +0 -3
- package/src/rust/components/column_selector/filter_column.rs +0 -3
- package/src/rust/components/column_selector/inactive_column.rs +2 -1
- package/src/rust/components/column_selector/invalid_column.rs +0 -4
- package/src/rust/components/column_selector.rs +0 -3
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +1 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +0 -3
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +0 -3
- package/src/rust/components/column_settings_sidebar.rs +1 -3
- package/src/rust/components/containers/dragdrop_list.rs +27 -0
- package/src/rust/components/containers/dropdown_menu.rs +1 -3
- package/src/rust/components/containers/scroll_panel.rs +1 -3
- package/src/rust/components/containers/split_panel.rs +0 -4
- package/src/rust/components/containers/tab_list.rs +0 -3
- package/src/rust/components/datetime_column_style.rs +0 -3
- package/src/rust/components/editable_header.rs +15 -0
- package/src/rust/components/empty_row.rs +0 -3
- package/src/rust/components/expression_editor.rs +2 -3
- package/src/rust/components/filter_dropdown.rs +3 -3
- package/src/rust/components/font_loader.rs +2 -2
- package/src/rust/components/form/code_editor.rs +0 -3
- package/src/rust/components/form/debug.rs +0 -4
- package/src/rust/components/function_dropdown.rs +3 -3
- package/src/rust/components/number_series_style.rs +0 -3
- package/src/rust/components/plugin_selector.rs +0 -3
- package/src/rust/components/plugin_tab.rs +0 -5
- package/src/rust/components/portal.rs +5 -2
- package/src/rust/components/render_warning.rs +0 -3
- package/src/rust/components/status_bar.rs +4 -3
- package/src/rust/components/string_column_style.rs +0 -3
- package/src/rust/components/style/mod.rs +60 -27
- package/src/rust/components/style/style_provider.rs +49 -16
- package/src/rust/components/style_controls/number_string_format.rs +1 -8
- package/src/rust/components/type_icon.rs +1 -4
- package/src/rust/components/viewer.rs +79 -5
- package/src/rust/custom_elements/copy_dropdown.rs +6 -2
- package/src/rust/custom_elements/export_dropdown.rs +6 -2
- package/src/rust/lib.rs +0 -1
- package/src/rust/renderer.rs +85 -21
- package/src/rust/session/metadata.rs +11 -1
- package/src/rust/session.rs +14 -1
- package/src/rust/tasks/reset_all.rs +38 -18
- package/src/rust/tasks/restore_and_render.rs +23 -12
- package/src/rust/tasks/send_column_config.rs +3 -2
- package/src/rust/tasks/send_plugin_config.rs +3 -2
- package/src/rust/tasks/update_and_render.rs +11 -4
- package/src/svg/checkbox-checked-icon.svg +1 -1
- package/src/svg/checkbox-unchecked-icon.svg +1 -1
- package/src/themes/botanical.css +2 -0
- package/src/themes/dracula.css +2 -0
- package/src/themes/gruvbox-dark.css +2 -0
- package/src/themes/icons.css +2 -0
- package/src/themes/intl/de.css +1 -0
- package/src/themes/intl/es.css +1 -0
- package/src/themes/intl/fr.css +1 -0
- package/src/themes/intl/ja.css +1 -0
- package/src/themes/intl/pt.css +1 -0
- package/src/themes/intl/zh.css +1 -0
- package/src/themes/intl.css +1 -0
- package/src/themes/monokai.css +2 -0
- package/src/themes/phosphor.css +2 -0
- package/src/themes/pro-dark.css +2 -0
- package/src/themes/vaporwave.css +2 -0
- package/tsconfig.json +1 -1
- package/src/rust/components/style/style_cache.rs +0 -136
- /package/dist/wasm/snippets/{perspective-viewer-39ab7da3ca157861 → perspective-viewer-93064d0d79855d97}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39ab7da3ca157861 → perspective-viewer-93064d0d79855d97}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39ab7da3ca157861 → perspective-viewer-93064d0d79855d97}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39ab7da3ca157861 → perspective-viewer-93064d0d79855d97}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39ab7da3ca157861 → perspective-viewer-93064d0d79855d97}/inline4.js +0 -0
|
@@ -19,9 +19,6 @@ use web_sys::HtmlElement;
|
|
|
19
19
|
use yew::html::Scope;
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
|
-
use crate::components::style::LocalStyle;
|
|
23
|
-
use crate::css;
|
|
24
|
-
|
|
25
22
|
#[derive(Properties, Default)]
|
|
26
23
|
pub struct SplitPanelProps {
|
|
27
24
|
pub children: Children,
|
|
@@ -201,7 +198,6 @@ impl Component for SplitPanel {
|
|
|
201
198
|
let count = iter.len();
|
|
202
199
|
let contents = html! {
|
|
203
200
|
<>
|
|
204
|
-
<LocalStyle href={css!("containers/split-panel")} />
|
|
205
201
|
for (i, x) in iter {
|
|
206
202
|
if i == 0 {
|
|
207
203
|
if count == 1 {
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
use yew::{Callback, Children, Component, Html, Properties, classes, html};
|
|
14
14
|
|
|
15
|
-
use crate::components::style::LocalStyle;
|
|
16
|
-
use crate::css;
|
|
17
15
|
use crate::presentation::ColumnTab;
|
|
18
16
|
|
|
19
17
|
#[derive(Properties, Debug, PartialEq)]
|
|
@@ -87,7 +85,6 @@ impl<T: ColumnTab> Component for TabList<T> {
|
|
|
87
85
|
|
|
88
86
|
html! {
|
|
89
87
|
<>
|
|
90
|
-
<LocalStyle href={css!("containers/tabs")} />
|
|
91
88
|
<div id="settings_tab_bar">{ for gutter_tabs }</div>
|
|
92
89
|
<div id="format-tab" class="tab-content scrollable">
|
|
93
90
|
{ ctx.props().children.iter().nth(self.selected_idx) }
|
|
@@ -23,12 +23,10 @@ use wasm_bindgen::prelude::*;
|
|
|
23
23
|
use yew::prelude::*;
|
|
24
24
|
|
|
25
25
|
use super::modal::{ModalLink, SetModalLink};
|
|
26
|
-
use super::style::LocalStyle;
|
|
27
26
|
use crate::components::datetime_column_style::custom::DatetimeStyleCustom;
|
|
28
27
|
use crate::components::datetime_column_style::simple::DatetimeStyleSimple;
|
|
29
28
|
use crate::components::form::select_value_field::SelectValueField;
|
|
30
29
|
use crate::config::*;
|
|
31
|
-
use crate::css;
|
|
32
30
|
use crate::utils::WeakScope;
|
|
33
31
|
|
|
34
32
|
/// Format-only widget for `datetime` columns. Renders the `date_format`
|
|
@@ -126,7 +124,6 @@ impl Component for DatetimeColumnStyle {
|
|
|
126
124
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
127
125
|
html! {
|
|
128
126
|
<>
|
|
129
|
-
<LocalStyle href={css!("column-style")} />
|
|
130
127
|
<div id="column-style-container" class="datetime-column-style-container">
|
|
131
128
|
if ctx.props().enable_time_config {
|
|
132
129
|
<SelectValueField<String>
|
|
@@ -28,9 +28,13 @@ pub struct EditableHeaderProps {
|
|
|
28
28
|
pub initial_value: Option<String>,
|
|
29
29
|
pub placeholder: Rc<String>,
|
|
30
30
|
|
|
31
|
+
// TODO remove this pattern
|
|
31
32
|
#[prop_or_default]
|
|
32
33
|
pub reset_count: u8,
|
|
33
34
|
|
|
35
|
+
#[prop_or_default]
|
|
36
|
+
pub update_on_input: bool,
|
|
37
|
+
|
|
34
38
|
/// Session metadata snapshot — threaded from `SessionProps`.
|
|
35
39
|
pub metadata: SessionMetadataRc,
|
|
36
40
|
|
|
@@ -163,6 +167,16 @@ impl Component for EditableHeader {
|
|
|
163
167
|
EditableHeaderMsg::SetNewValue(value)
|
|
164
168
|
});
|
|
165
169
|
|
|
170
|
+
let update_on_input = ctx.props().update_on_input;
|
|
171
|
+
let oninput = ctx.link().batch_callback(move |e: yew::InputEvent| {
|
|
172
|
+
if update_on_input {
|
|
173
|
+
let value = e.target_unchecked_into::<HtmlInputElement>().value();
|
|
174
|
+
vec![EditableHeaderMsg::SetNewValue(value)]
|
|
175
|
+
} else {
|
|
176
|
+
vec![]
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
166
180
|
html! {
|
|
167
181
|
<div class={classes} onclick={ctx.link().callback(|_| EditableHeaderMsg::OnClick(()))}>
|
|
168
182
|
if let Some(icon) = ctx.props().icon_type { <TypeIcon ty={icon} /> }
|
|
@@ -173,6 +187,7 @@ impl Component for EditableHeader {
|
|
|
173
187
|
disabled={!ctx.props().editable}
|
|
174
188
|
{onblur}
|
|
175
189
|
{onkeyup}
|
|
190
|
+
{oninput}
|
|
176
191
|
value={self.value.clone()}
|
|
177
192
|
placeholder={self.placeholder.clone()}
|
|
178
193
|
/>
|
|
@@ -20,8 +20,6 @@ use web_sys::*;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use crate::components::filter_dropdown::FilterDropDownElement;
|
|
23
|
-
use crate::components::style::LocalStyle;
|
|
24
|
-
use crate::css;
|
|
25
23
|
|
|
26
24
|
#[derive(Properties, Derivative)]
|
|
27
25
|
#[derivative(Debug)]
|
|
@@ -87,7 +85,6 @@ impl Component for EmptyRow {
|
|
|
87
85
|
|
|
88
86
|
html! {
|
|
89
87
|
<div class="pivot-column column-empty">
|
|
90
|
-
<LocalStyle href={css!("empty-column")} />
|
|
91
88
|
<input
|
|
92
89
|
spellcheck="false"
|
|
93
90
|
ref={self.input_ref.clone()}
|
|
@@ -16,10 +16,8 @@ use perspective_client::{ExprValidationError, clone};
|
|
|
16
16
|
use yew::prelude::*;
|
|
17
17
|
|
|
18
18
|
use super::form::code_editor::*;
|
|
19
|
-
use super::style::LocalStyle;
|
|
20
19
|
use crate::session::{Session, SessionMetadata, SessionMetadataRc};
|
|
21
20
|
use crate::tasks::{ExprValidation, validate_expression};
|
|
22
|
-
use crate::*;
|
|
23
21
|
|
|
24
22
|
#[derive(Properties, PartialEq, Clone)]
|
|
25
23
|
pub struct ExpressionEditorProps {
|
|
@@ -54,10 +52,12 @@ pub struct ExpressionEditor {
|
|
|
54
52
|
expr: Rc<String>,
|
|
55
53
|
error: Option<ExprValidationError>,
|
|
56
54
|
oninput: Callback<Rc<String>>,
|
|
55
|
+
|
|
57
56
|
/// Monotonically increasing request id used to drop stale
|
|
58
57
|
/// validation results when the user types faster than the engine
|
|
59
58
|
/// can validate.
|
|
60
59
|
validation_req_id: u64,
|
|
60
|
+
|
|
61
61
|
/// The id of the most recently dispatched validation; the result
|
|
62
62
|
/// is only applied when its echoed id matches.
|
|
63
63
|
last_dispatched_req_id: u64,
|
|
@@ -131,7 +131,6 @@ impl Component for ExpressionEditor {
|
|
|
131
131
|
clone!(ctx.props().disabled);
|
|
132
132
|
html! {
|
|
133
133
|
<>
|
|
134
|
-
<LocalStyle href={css!("expression-editor")} />
|
|
135
134
|
<label class="item_title">{ "Expression" }</label>
|
|
136
135
|
<div id="editor-container" class={disabled_class}>
|
|
137
136
|
<CodeEditor
|
|
@@ -20,12 +20,11 @@ use yew::html::ImplicitClone;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use super::portal::PortalModal;
|
|
23
|
+
use super::style::StyleSurface;
|
|
23
24
|
use crate::session::Session;
|
|
24
25
|
use crate::utils::*;
|
|
25
26
|
use crate::*;
|
|
26
27
|
|
|
27
|
-
static CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/css/filter-dropdown.css"));
|
|
28
|
-
|
|
29
28
|
#[derive(Default)]
|
|
30
29
|
struct FilterDropDownState {
|
|
31
30
|
values: Vec<String>,
|
|
@@ -220,6 +219,7 @@ impl Component for FilterDropDownPortal {
|
|
|
220
219
|
html! {
|
|
221
220
|
<PortalModal
|
|
222
221
|
tag_name="perspective-dropdown"
|
|
222
|
+
surface={StyleSurface::FilterDropdown}
|
|
223
223
|
{target}
|
|
224
224
|
own_focus=false
|
|
225
225
|
{on_close}
|
|
@@ -267,7 +267,7 @@ fn FilterDropDownView(props: &FilterDropDownViewProps) -> Html {
|
|
|
267
267
|
}
|
|
268
268
|
};
|
|
269
269
|
|
|
270
|
-
html! {
|
|
270
|
+
html! { <>{ body }</> }
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
fn filter_values(
|
|
@@ -154,12 +154,12 @@ impl FontLoaderProps {
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
let fut = async { select_all(block_fonts
|
|
157
|
+
let fut = async { select_all(block_fonts).await.0 };
|
|
158
158
|
block_promises.push(ApiFuture::new(fut))
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
if block_promises.len() != preload_fonts.len() {
|
|
162
|
-
web_sys::console::warn_1(&format!("Missing preload fonts {:?}",
|
|
162
|
+
web_sys::console::warn_1(&format!("Missing preload fonts {:?}", preload_fonts).into());
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
let res = join_all(block_promises)
|
|
@@ -19,8 +19,6 @@ use yew::prelude::*;
|
|
|
19
19
|
|
|
20
20
|
use crate::components::form::highlight::highlight;
|
|
21
21
|
use crate::components::function_dropdown::{FunctionDropDownElement, FunctionDropDownPortal};
|
|
22
|
-
use crate::components::style::LocalStyle;
|
|
23
|
-
use crate::css;
|
|
24
22
|
use crate::exprtk::{Cursor, tokenize};
|
|
25
23
|
use crate::utils::*;
|
|
26
24
|
|
|
@@ -174,7 +172,6 @@ pub fn code_editor(props: &CodeEditorProps) -> Html {
|
|
|
174
172
|
clone!(props.disabled);
|
|
175
173
|
html! {
|
|
176
174
|
<>
|
|
177
|
-
<LocalStyle href={css!("form/code-editor")} />
|
|
178
175
|
<div id="editor" {class}>
|
|
179
176
|
<div id="line_numbers" ref={lineno_ref}>{ line_numbers }</div>
|
|
180
177
|
<div id="editor-inner" {class}>
|
|
@@ -18,8 +18,6 @@ use wasm_bindgen::prelude::*;
|
|
|
18
18
|
use yew::prelude::*;
|
|
19
19
|
|
|
20
20
|
use crate::components::form::code_editor::CodeEditor;
|
|
21
|
-
use crate::components::style::LocalStyle;
|
|
22
|
-
use crate::css;
|
|
23
21
|
use crate::js::{MimeType, copy_to_clipboard, paste_from_clipboard};
|
|
24
22
|
use crate::presentation::*;
|
|
25
23
|
use crate::renderer::*;
|
|
@@ -166,8 +164,6 @@ pub fn debug_panel(props: &DebugPanelProps) -> Html {
|
|
|
166
164
|
|
|
167
165
|
html! {
|
|
168
166
|
<>
|
|
169
|
-
<LocalStyle href={css!("containers/tabs")} />
|
|
170
|
-
<LocalStyle href={css!("form/debug")} />
|
|
171
167
|
<div id="debug-panel-overflow">
|
|
172
168
|
<div id="debug-panel" class="sidebar_column" ref={sizer}>
|
|
173
169
|
<div id="debug-panel-controls">
|
|
@@ -20,10 +20,9 @@ use yew::html::ImplicitClone;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use super::portal::PortalModal;
|
|
23
|
+
use super::style::StyleSurface;
|
|
23
24
|
use crate::utils::*;
|
|
24
25
|
|
|
25
|
-
static CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/css/function-dropdown.css"));
|
|
26
|
-
|
|
27
26
|
#[derive(Default)]
|
|
28
27
|
struct FunctionDropDownState {
|
|
29
28
|
values: Vec<CompletionItemSuggestion>,
|
|
@@ -158,6 +157,7 @@ impl Component for FunctionDropDownPortal {
|
|
|
158
157
|
html! {
|
|
159
158
|
<PortalModal
|
|
160
159
|
tag_name="perspective-dropdown"
|
|
160
|
+
surface={StyleSurface::FunctionDropdown}
|
|
161
161
|
{target}
|
|
162
162
|
own_focus=false
|
|
163
163
|
{on_close}
|
|
@@ -211,7 +211,7 @@ fn FunctionDropDownView(props: &FunctionDropDownViewProps) -> Html {
|
|
|
211
211
|
}
|
|
212
212
|
};
|
|
213
213
|
|
|
214
|
-
html! {
|
|
214
|
+
html! { <>{ body }</> }
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
fn filter_values(input: &str) -> Vec<CompletionItemSuggestion> {
|
|
@@ -14,10 +14,8 @@ use web_sys::{HtmlInputElement, InputEvent};
|
|
|
14
14
|
use yew::prelude::*;
|
|
15
15
|
|
|
16
16
|
use super::modal::{ModalLink, SetModalLink};
|
|
17
|
-
use super::style::LocalStyle;
|
|
18
17
|
use crate::components::form::select_enum_field::SelectEnumField;
|
|
19
18
|
use crate::config::*;
|
|
20
|
-
use crate::css;
|
|
21
19
|
use crate::utils::WeakScope;
|
|
22
20
|
|
|
23
21
|
#[derive(Properties)]
|
|
@@ -125,7 +123,6 @@ impl Component for NumberSeriesStyle {
|
|
|
125
123
|
|
|
126
124
|
html! {
|
|
127
125
|
<>
|
|
128
|
-
<LocalStyle href={css!("column-style")} />
|
|
129
126
|
<div id="column-style-container" class="number-series-style-container">
|
|
130
127
|
<SelectEnumField<ChartType>
|
|
131
128
|
label="chart-type"
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
use yew::prelude::*;
|
|
14
14
|
|
|
15
|
-
use super::style::LocalStyle;
|
|
16
|
-
use crate::css;
|
|
17
15
|
use crate::utils::PtrEqRc;
|
|
18
16
|
|
|
19
17
|
/// Pure value props — no engine handles, no PubSub subscriptions.
|
|
@@ -85,7 +83,6 @@ impl Component for PluginSelector {
|
|
|
85
83
|
|
|
86
84
|
html! {
|
|
87
85
|
<>
|
|
88
|
-
<LocalStyle href={css!("plugin-selector")} />
|
|
89
86
|
<div id="plugin_selector_container" {class}>
|
|
90
87
|
<PluginSelect name={plugin_name} on_click={callback} />
|
|
91
88
|
<div id="plugin_selector_border" />
|
|
@@ -22,9 +22,7 @@ use yew::prelude::*;
|
|
|
22
22
|
use crate::components::column_settings_sidebar::style_tab::primitive_field::{
|
|
23
23
|
BoolField, ColorField, ColorRangeField, EnumField, NumberFieldPrimitive,
|
|
24
24
|
};
|
|
25
|
-
use crate::components::style::LocalStyle;
|
|
26
25
|
use crate::config::ControlSpec;
|
|
27
|
-
use crate::css;
|
|
28
26
|
use crate::queries::get_plugin_config_schema;
|
|
29
27
|
use crate::renderer::Renderer;
|
|
30
28
|
use crate::session::Session;
|
|
@@ -212,9 +210,6 @@ pub fn PluginTab(props: &PluginTabProps) -> Html {
|
|
|
212
210
|
|
|
213
211
|
html! {
|
|
214
212
|
<div id="plugin-tab" class="sidebar_column scrollable">
|
|
215
|
-
<LocalStyle href={css!("column-style")} />
|
|
216
|
-
<LocalStyle href={css!("plugin-settings-panel")} />
|
|
217
|
-
<LocalStyle href={css!("containers/tabs")} />
|
|
218
213
|
<div id="plugin-config-container" class="tab-section">{ components }</div>
|
|
219
214
|
</div>
|
|
220
215
|
}
|
|
@@ -20,7 +20,7 @@ use web_sys::*;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use crate::components::modal::ModalOrientation;
|
|
23
|
-
use crate::components::style::StyleProvider;
|
|
23
|
+
use crate::components::style::{StyleProvider, StyleSurface};
|
|
24
24
|
use crate::utils::*;
|
|
25
25
|
|
|
26
26
|
#[derive(Properties, PartialEq)]
|
|
@@ -41,6 +41,9 @@ pub struct PortalModalProps {
|
|
|
41
41
|
pub tag_name: &'static str,
|
|
42
42
|
|
|
43
43
|
pub theme: String,
|
|
44
|
+
|
|
45
|
+
/// Which popup CSS surface this portal's ShadowRoot adopts.
|
|
46
|
+
pub surface: StyleSurface,
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
pub enum PortalModalMsg {
|
|
@@ -209,7 +212,7 @@ impl Component for PortalModal {
|
|
|
209
212
|
<>
|
|
210
213
|
<style>{ css }</style>
|
|
211
214
|
<ContextProvider<ModalOrientation> context={self.rev_vert.clone()}>
|
|
212
|
-
<StyleProvider root={self.host.clone()}>
|
|
215
|
+
<StyleProvider root={self.host.clone()} surface={ctx.props().surface}>
|
|
213
216
|
{ for ctx.props().children.iter() }
|
|
214
217
|
</StyleProvider>
|
|
215
218
|
</ContextProvider<ModalOrientation>>
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
use yew::prelude::*;
|
|
14
14
|
|
|
15
|
-
use super::style::LocalStyle;
|
|
16
|
-
use crate::css;
|
|
17
15
|
use crate::renderer::limits::RenderLimits;
|
|
18
16
|
|
|
19
17
|
#[derive(Properties, PartialEq)]
|
|
@@ -81,7 +79,6 @@ pub fn render_warning(props: &RenderWarningProps) -> Html {
|
|
|
81
79
|
let onclick = Callback::from(move |_: MouseEvent| on_dismiss.emit(()));
|
|
82
80
|
html! {
|
|
83
81
|
<>
|
|
84
|
-
<LocalStyle href={css!("render-warning")} />
|
|
85
82
|
<div
|
|
86
83
|
class="plugin_information plugin_information--warning"
|
|
87
84
|
id="plugin_information--size"
|
|
@@ -15,12 +15,12 @@ use web_sys::*;
|
|
|
15
15
|
use yew::prelude::*;
|
|
16
16
|
|
|
17
17
|
use super::status_indicator::StatusIndicator;
|
|
18
|
-
use super::style::LocalStyle;
|
|
19
18
|
use crate::components::containers::select::*;
|
|
20
19
|
use crate::components::copy_dropdown::CopyDropDownMenu;
|
|
21
20
|
use crate::components::export_dropdown::ExportDropDownMenu;
|
|
22
21
|
use crate::components::portal::PortalModal;
|
|
23
22
|
use crate::components::status_bar_counter::StatusBarRowsCounter;
|
|
23
|
+
use crate::components::style::StyleSurface;
|
|
24
24
|
use crate::config::*;
|
|
25
25
|
use crate::js::*;
|
|
26
26
|
use crate::presentation::{Presentation, PresentationProps};
|
|
@@ -332,7 +332,6 @@ impl Component for StatusBar {
|
|
|
332
332
|
if is_settings {
|
|
333
333
|
html! {
|
|
334
334
|
<>
|
|
335
|
-
<LocalStyle href={css!("status-bar")} />
|
|
336
335
|
<div
|
|
337
336
|
ref={&self.statusbar_ref}
|
|
338
337
|
id={ctx.props().id.clone()}
|
|
@@ -377,7 +376,7 @@ impl Component for StatusBar {
|
|
|
377
376
|
<div id="plugin-settings"><slot name="statusbar-extra" /></div>
|
|
378
377
|
<span class="hover-target">
|
|
379
378
|
<span id="reset" class="button" onmousedown={&onreset}>
|
|
380
|
-
<span class="icon" />
|
|
379
|
+
<span class="icon shift-alt-icon" />
|
|
381
380
|
<span class="icon-label" />
|
|
382
381
|
</span>
|
|
383
382
|
</span>
|
|
@@ -418,6 +417,7 @@ impl Component for StatusBar {
|
|
|
418
417
|
</div>
|
|
419
418
|
<PortalModal
|
|
420
419
|
tag_name="perspective-copy-menu"
|
|
420
|
+
surface={StyleSurface::DropdownMenu}
|
|
421
421
|
target={self.copy_target.clone()}
|
|
422
422
|
own_focus=true
|
|
423
423
|
on_close={on_close_copy}
|
|
@@ -427,6 +427,7 @@ impl Component for StatusBar {
|
|
|
427
427
|
</PortalModal>
|
|
428
428
|
<PortalModal
|
|
429
429
|
tag_name="perspective-export-menu"
|
|
430
|
+
surface={StyleSurface::DropdownMenu}
|
|
430
431
|
target={self.export_target.clone()}
|
|
431
432
|
own_focus=true
|
|
432
433
|
on_close={on_close_export}
|
|
@@ -13,10 +13,8 @@
|
|
|
13
13
|
use yew::prelude::*;
|
|
14
14
|
|
|
15
15
|
use super::modal::{ModalLink, SetModalLink};
|
|
16
|
-
use super::style::LocalStyle;
|
|
17
16
|
use crate::components::form::select_enum_field::SelectEnumField;
|
|
18
17
|
use crate::config::*;
|
|
19
|
-
use crate::css;
|
|
20
18
|
use crate::utils::WeakScope;
|
|
21
19
|
|
|
22
20
|
/// Format-only widget for [`String`] columns. Renders the `format` enum
|
|
@@ -91,7 +89,6 @@ impl Component for StringColumnStyle {
|
|
|
91
89
|
let format_mode_changed = ctx.link().callback(StringColumnStyleMsg::FormatChanged);
|
|
92
90
|
html! {
|
|
93
91
|
<>
|
|
94
|
-
<LocalStyle href={css!("column-style")} />
|
|
95
92
|
<div id="column-style-container" class="string-column-style-container">
|
|
96
93
|
<SelectEnumField<FormatMode>
|
|
97
94
|
label="format"
|
|
@@ -10,43 +10,76 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
//!
|
|
14
|
-
//!
|
|
13
|
+
//! Associates a single, build-time CSS bundle with a `yew::Component` tree
|
|
14
|
+
//! rendered into a Custom Element's `ShadowRoot`.
|
|
15
15
|
//!
|
|
16
|
-
//!
|
|
17
|
-
//!
|
|
18
|
-
//!
|
|
16
|
+
//! Each `src/css` file is inlined and minified by `lightningcss` (see
|
|
17
|
+
//! `build.rs` + the `_viewer_bundle.css` and per-popup `_column_dropdown.css`
|
|
18
|
+
//! / `_filter_dropdown.css` / `_function_dropdown.css` / `_dropdown_menu.css`
|
|
19
|
+
//! entrypoints) into one stylesheet per "surface". A `<StyleProvider>` at the
|
|
20
|
+
//! root of a shadow tree adopts its surface's stylesheet exactly once;
|
|
21
|
+
//! constructed `CSSStyleSheet`s are cheap and shared across every viewer
|
|
22
|
+
//! instance.
|
|
19
23
|
//!
|
|
20
24
|
//! # Example
|
|
21
25
|
//!
|
|
22
|
-
//! ```
|
|
26
|
+
//! ```ignore
|
|
23
27
|
//! html! {
|
|
24
|
-
//! <StyleProvider>
|
|
25
|
-
//! <LocalStyle href={ css!("my-style") } />
|
|
28
|
+
//! <StyleProvider root={host} surface={StyleSurface::Viewer}>
|
|
26
29
|
//! <h1>{ "I am styled!" }</h1>
|
|
27
30
|
//! </StyleProvider>
|
|
28
31
|
//! }
|
|
29
32
|
//! ```
|
|
30
33
|
|
|
31
|
-
mod local_style;
|
|
32
|
-
mod style_cache;
|
|
33
34
|
mod style_provider;
|
|
34
35
|
|
|
35
|
-
pub use
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
pub use style_provider::{StyleProvider, StyleSurface};
|
|
37
|
+
|
|
38
|
+
/// The viewer-surface bundle: every `src/css` file except the floating-popup
|
|
39
|
+
/// sheets. Adopted into the `<perspective-viewer>` ShadowRoot.
|
|
40
|
+
fn viewer_bundle() -> &'static str {
|
|
41
|
+
include_str!(concat!(env!("OUT_DIR"), "/css/_viewer_bundle.css"))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Per-popup-surface bundles. Each floating popup root adopts exactly its own
|
|
45
|
+
/// self-contained sheet (mirroring the pre-bundle behavior where every popup
|
|
46
|
+
/// instance carried only its own CSS) so the four popup styles never collide —
|
|
47
|
+
/// in particular `column-dropdown.css`'s `!important` inverted rules stay
|
|
48
|
+
/// confined to the column-name completion dropdown.
|
|
49
|
+
fn column_dropdown_bundle() -> &'static str {
|
|
50
|
+
include_str!(concat!(env!("OUT_DIR"), "/css/_column_dropdown.css"))
|
|
51
|
+
}
|
|
52
|
+
fn filter_dropdown_bundle() -> &'static str {
|
|
53
|
+
include_str!(concat!(env!("OUT_DIR"), "/css/_filter_dropdown.css"))
|
|
54
|
+
}
|
|
55
|
+
fn function_dropdown_bundle() -> &'static str {
|
|
56
|
+
include_str!(concat!(env!("OUT_DIR"), "/css/_function_dropdown.css"))
|
|
57
|
+
}
|
|
58
|
+
fn dropdown_menu_bundle() -> &'static str {
|
|
59
|
+
include_str!(concat!(env!("OUT_DIR"), "/css/_dropdown_menu.css"))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
thread_local! {
|
|
63
|
+
static VIEWER_SHEET: web_sys::CssStyleSheet = make_sheet(viewer_bundle());
|
|
64
|
+
static COLUMN_DROPDOWN_SHEET: web_sys::CssStyleSheet = make_sheet(column_dropdown_bundle());
|
|
65
|
+
static FILTER_DROPDOWN_SHEET: web_sys::CssStyleSheet = make_sheet(filter_dropdown_bundle());
|
|
66
|
+
static FUNCTION_DROPDOWN_SHEET: web_sys::CssStyleSheet = make_sheet(function_dropdown_bundle());
|
|
67
|
+
static DROPDOWN_MENU_SHEET: web_sys::CssStyleSheet = make_sheet(dropdown_menu_bundle());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fn make_sheet(css: &str) -> web_sys::CssStyleSheet {
|
|
71
|
+
let sheet = web_sys::CssStyleSheet::new().unwrap();
|
|
72
|
+
sheet.replace_sync(css).unwrap();
|
|
73
|
+
sheet
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// The memoized, shared `CSSStyleSheet` for a given [`StyleSurface`].
|
|
77
|
+
pub(crate) fn surface_sheet(surface: StyleSurface) -> web_sys::CssStyleSheet {
|
|
78
|
+
match surface {
|
|
79
|
+
StyleSurface::Viewer => VIEWER_SHEET.with(|x| x.clone()),
|
|
80
|
+
StyleSurface::ColumnDropdown => COLUMN_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
81
|
+
StyleSurface::FilterDropdown => FILTER_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
82
|
+
StyleSurface::FunctionDropdown => FUNCTION_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
83
|
+
StyleSurface::DropdownMenu => DROPDOWN_MENU_SHEET.with(|x| x.clone()),
|
|
84
|
+
}
|
|
52
85
|
}
|
|
@@ -10,9 +10,26 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
+
use wasm_bindgen::{JsCast, JsValue};
|
|
13
14
|
use yew::prelude::*;
|
|
14
15
|
|
|
15
|
-
use super::
|
|
16
|
+
use super::surface_sheet;
|
|
17
|
+
|
|
18
|
+
/// Which prebuilt CSS bundle a [`StyleProvider`] adopts into its root.
|
|
19
|
+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
|
20
|
+
pub enum StyleSurface {
|
|
21
|
+
/// The `<perspective-viewer>` ShadowRoot.
|
|
22
|
+
#[default]
|
|
23
|
+
Viewer,
|
|
24
|
+
/// Column-name completion dropdown (inverted color scheme).
|
|
25
|
+
ColumnDropdown,
|
|
26
|
+
/// Filter-value completion dropdown.
|
|
27
|
+
FilterDropdown,
|
|
28
|
+
/// Expression function-completion dropdown.
|
|
29
|
+
FunctionDropdown,
|
|
30
|
+
/// Copy / Export menu (non-inverted color scheme).
|
|
31
|
+
DropdownMenu,
|
|
32
|
+
}
|
|
16
33
|
|
|
17
34
|
#[derive(Properties, PartialEq)]
|
|
18
35
|
pub struct StyleProviderProps {
|
|
@@ -20,32 +37,48 @@ pub struct StyleProviderProps {
|
|
|
20
37
|
|
|
21
38
|
#[prop_or(true)]
|
|
22
39
|
pub is_shadow: bool,
|
|
40
|
+
|
|
41
|
+
#[prop_or_default]
|
|
42
|
+
pub surface: StyleSurface,
|
|
43
|
+
|
|
23
44
|
pub children: Children,
|
|
24
45
|
}
|
|
25
46
|
|
|
26
|
-
///
|
|
27
|
-
///
|
|
28
|
-
///
|
|
29
|
-
|
|
30
|
-
/// and `css!()` resource inlining macro.
|
|
31
|
-
pub struct StyleProvider {
|
|
32
|
-
cache: StyleCache,
|
|
33
|
-
}
|
|
47
|
+
/// Adopts the build-time CSS bundle for its [`StyleSurface`] into the root's
|
|
48
|
+
/// `adoptedStyleSheets` once, on creation. Unlike the previous per-snippet
|
|
49
|
+
/// `LocalStyle` registration, children no longer register CSS individually.
|
|
50
|
+
pub struct StyleProvider;
|
|
34
51
|
|
|
35
52
|
impl Component for StyleProvider {
|
|
36
53
|
type Message = ();
|
|
37
54
|
type Properties = StyleProviderProps;
|
|
38
55
|
|
|
39
56
|
fn create(ctx: &Context<Self>) -> Self {
|
|
40
|
-
|
|
41
|
-
Self
|
|
57
|
+
adopt_surface_sheet(ctx.props());
|
|
58
|
+
Self
|
|
42
59
|
}
|
|
43
60
|
|
|
44
61
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
45
|
-
html! {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
html! { <>{ for ctx.props().children.iter() }</> }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// Push the surface's shared stylesheet onto the root's `adoptedStyleSheets`,
|
|
67
|
+
/// unless it is already present (a root may host more than one provider).
|
|
68
|
+
fn adopt_surface_sheet(props: &StyleProviderProps) {
|
|
69
|
+
let root: JsValue = if props.is_shadow {
|
|
70
|
+
props.root.shadow_root().unwrap().into()
|
|
71
|
+
} else {
|
|
72
|
+
web_sys::window().unwrap().document().unwrap().into()
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
let sheets = js_sys::Reflect::get(&root, &"adoptedStyleSheets".into())
|
|
76
|
+
.unwrap()
|
|
77
|
+
.unchecked_into::<js_sys::Array>();
|
|
78
|
+
|
|
79
|
+
let sheet = surface_sheet(props.surface);
|
|
80
|
+
let sheet_val: &JsValue = sheet.as_ref();
|
|
81
|
+
if sheets.index_of(sheet_val, 0) < 0 {
|
|
82
|
+
sheets.push(sheet_val);
|
|
50
83
|
}
|
|
51
84
|
}
|
|
@@ -19,9 +19,7 @@ use perspective_client::config::ColumnType;
|
|
|
19
19
|
pub use types::*;
|
|
20
20
|
use yew::{Callback, Component, Properties, html};
|
|
21
21
|
|
|
22
|
-
use crate::components::style::LocalStyle;
|
|
23
22
|
use crate::config::*;
|
|
24
|
-
use crate::css;
|
|
25
23
|
|
|
26
24
|
#[derive(Properties, PartialEq, Clone)]
|
|
27
25
|
pub struct CustomNumberFormatProps {
|
|
@@ -211,12 +209,7 @@ impl Component for CustomNumberFormat {
|
|
|
211
209
|
|
|
212
210
|
fn view(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
213
211
|
html! {
|
|
214
|
-
<>
|
|
215
|
-
<LocalStyle href={css!("column-style")} />
|
|
216
|
-
{ self.style_section(ctx) }
|
|
217
|
-
{ self.digits_section(ctx) }
|
|
218
|
-
{ self.misc_section(ctx) }
|
|
219
|
-
</>
|
|
212
|
+
<>{ self.style_section(ctx) }{ self.digits_section(ctx) }{ self.misc_section(ctx) }</>
|
|
220
213
|
}
|
|
221
214
|
}
|
|
222
215
|
}
|