@perspective-dev/viewer 4.5.1 → 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/monokai.css +1 -1
- package/dist/css/phosphor.css +1 -1
- package/dist/css/pro-dark.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 +69 -69
- 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/viewer.css +2 -2
- package/src/rust/components/column_dropdown.rs +3 -3
- 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/invalid_column.rs +0 -4
- package/src/rust/components/column_selector.rs +0 -3
- 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 +0 -3
- 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/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 +3 -2
- 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 +1 -3
- 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 +13 -3
- package/src/rust/session/metadata.rs +11 -1
- package/src/rust/session.rs +14 -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/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-3cd58f0374935772 → perspective-viewer-93064d0d79855d97}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-3cd58f0374935772 → perspective-viewer-93064d0d79855d97}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-3cd58f0374935772 → perspective-viewer-93064d0d79855d97}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-3cd58f0374935772 → perspective-viewer-93064d0d79855d97}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-3cd58f0374935772 → perspective-viewer-93064d0d79855d97}/inline4.js +0 -0
|
@@ -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
|
}
|
|
@@ -14,9 +14,6 @@ use perspective_client::config::ColumnType;
|
|
|
14
14
|
use yew::html::IntoPropValue;
|
|
15
15
|
use yew::{Properties, classes, function_component, html};
|
|
16
16
|
|
|
17
|
-
use crate::components::style::LocalStyle;
|
|
18
|
-
use crate::css;
|
|
19
|
-
|
|
20
17
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
|
21
18
|
pub enum TypeIconType {
|
|
22
19
|
Type(ColumnType),
|
|
@@ -31,7 +28,7 @@ pub struct TypeIconProps {
|
|
|
31
28
|
#[function_component(TypeIcon)]
|
|
32
29
|
pub fn type_icon(p: &TypeIconProps) -> yew::Html {
|
|
33
30
|
let class = classes!(p.ty.to_string(), "type-icon");
|
|
34
|
-
html! { <><
|
|
31
|
+
html! { <><span {class} /></> }
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
impl From<ColumnType> for TypeIconType {
|
|
@@ -21,12 +21,11 @@ use yew::prelude::*;
|
|
|
21
21
|
|
|
22
22
|
use super::containers::split_panel::SplitPanel;
|
|
23
23
|
use super::font_loader::{FontLoader, FontLoaderProps, FontLoaderStatus};
|
|
24
|
-
use super::style::
|
|
24
|
+
use super::style::StyleProvider;
|
|
25
25
|
use crate::components::column_settings_sidebar::ColumnSettingsPanel;
|
|
26
26
|
use crate::components::main_panel::MainPanel;
|
|
27
27
|
use crate::components::settings_panel::{SelectedTab, SettingsPanel};
|
|
28
28
|
use crate::config::*;
|
|
29
|
-
use crate::css;
|
|
30
29
|
use crate::js::JsPerspectiveViewerPlugin;
|
|
31
30
|
use crate::presentation::{
|
|
32
31
|
ColumnLocator, ColumnSettingsTab, DragDropProps, Presentation, PresentationProps,
|
|
@@ -608,7 +607,6 @@ impl Component for PerspectiveViewer {
|
|
|
608
607
|
|
|
609
608
|
html! {
|
|
610
609
|
<StyleProvider root={ctx.props().elem.clone()}>
|
|
611
|
-
<LocalStyle href={css!("viewer")} />
|
|
612
610
|
<div id="component_container">
|
|
613
611
|
if is_settings_open {
|
|
614
612
|
<SplitPanel
|
|
@@ -22,7 +22,7 @@ use yew::prelude::*;
|
|
|
22
22
|
use super::viewer::PerspectiveViewerElement;
|
|
23
23
|
use crate::components::copy_dropdown::CopyDropDownMenu;
|
|
24
24
|
use crate::components::portal::PortalModal;
|
|
25
|
-
use crate::components::style::StyleProvider;
|
|
25
|
+
use crate::components::style::{StyleProvider, StyleSurface};
|
|
26
26
|
use crate::config::*;
|
|
27
27
|
use crate::js::*;
|
|
28
28
|
use crate::presentation::Presentation;
|
|
@@ -77,9 +77,13 @@ impl Component for CopyDropDownWrapper {
|
|
|
77
77
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
78
78
|
let on_close = ctx.link().callback(|_| CopyDropDownWrapperMsg::Close);
|
|
79
79
|
html! {
|
|
80
|
-
<StyleProvider
|
|
80
|
+
<StyleProvider
|
|
81
|
+
root={ctx.props().custom_element.clone()}
|
|
82
|
+
surface={StyleSurface::DropdownMenu}
|
|
83
|
+
>
|
|
81
84
|
<PortalModal
|
|
82
85
|
tag_name="perspective-copy-menu"
|
|
86
|
+
surface={StyleSurface::DropdownMenu}
|
|
83
87
|
target={self.target.clone()}
|
|
84
88
|
own_focus=true
|
|
85
89
|
{on_close}
|
|
@@ -22,7 +22,7 @@ use yew::prelude::*;
|
|
|
22
22
|
use super::viewer::PerspectiveViewerElement;
|
|
23
23
|
use crate::components::export_dropdown::ExportDropDownMenu;
|
|
24
24
|
use crate::components::portal::PortalModal;
|
|
25
|
-
use crate::components::style::StyleProvider;
|
|
25
|
+
use crate::components::style::{StyleProvider, StyleSurface};
|
|
26
26
|
use crate::config::*;
|
|
27
27
|
use crate::presentation::Presentation;
|
|
28
28
|
use crate::renderer::*;
|
|
@@ -77,9 +77,13 @@ impl Component for ExportDropDownWrapper {
|
|
|
77
77
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
78
78
|
let on_close = ctx.link().callback(|_| ExportDropDownWrapperMsg::Close);
|
|
79
79
|
html! {
|
|
80
|
-
<StyleProvider
|
|
80
|
+
<StyleProvider
|
|
81
|
+
root={ctx.props().custom_element.clone()}
|
|
82
|
+
surface={StyleSurface::DropdownMenu}
|
|
83
|
+
>
|
|
81
84
|
<PortalModal
|
|
82
85
|
tag_name="perspective-export-menu"
|
|
86
|
+
surface={StyleSurface::DropdownMenu}
|
|
83
87
|
target={self.target.clone()}
|
|
84
88
|
own_focus=true
|
|
85
89
|
{on_close}
|
package/src/rust/lib.rs
CHANGED
package/src/rust/renderer.rs
CHANGED
|
@@ -544,6 +544,16 @@ impl Renderer {
|
|
|
544
544
|
.and_then(|idx| names.get(idx))
|
|
545
545
|
.map(|s| s.as_str());
|
|
546
546
|
|
|
547
|
+
// If the view schema itself hasn't been built yet (e.g. restore
|
|
548
|
+
// landed before `create_view` populated `view_schema`), refuse
|
|
549
|
+
// to answer rather than returning an empty schema. The strip
|
|
550
|
+
// pass in `update_columns_configs` treats `Err` as "leave the
|
|
551
|
+
// incoming cfg untouched"; an empty schema, by contrast, would
|
|
552
|
+
// cause `cfg.retain(|k, _| active.contains(k))` to drop every
|
|
553
|
+
// key and zero out user-supplied column config.
|
|
554
|
+
if !session.metadata().has_view_schema() {
|
|
555
|
+
return Err(JsValue::from("view_schema not initialized").into());
|
|
556
|
+
}
|
|
547
557
|
let Some(view_type) = session.metadata().get_column_view_type(column_name) else {
|
|
548
558
|
return Ok(ColumnConfigSchema { fields: vec![] });
|
|
549
559
|
};
|
|
@@ -1040,7 +1050,7 @@ impl Renderer {
|
|
|
1040
1050
|
}),
|
|
1041
1051
|
];
|
|
1042
1052
|
|
|
1043
|
-
let (x, _, y) = select_all(tasks
|
|
1053
|
+
let (x, _, y) = select_all(tasks).await;
|
|
1044
1054
|
x.ok_or_else(|| y.into_iter().next().unwrap())
|
|
1045
1055
|
}
|
|
1046
1056
|
|
|
@@ -1048,8 +1058,8 @@ impl Renderer {
|
|
|
1048
1058
|
async fn resize_with_explicit_dimensions(&self) -> TaskResult {
|
|
1049
1059
|
let plugin = self.get_active_plugin()?;
|
|
1050
1060
|
let main_panel: &web_sys::HtmlElement = plugin.unchecked_ref();
|
|
1051
|
-
let new_width = format!("{}px",
|
|
1052
|
-
let new_height = format!("{}px",
|
|
1061
|
+
let new_width = format!("{}px", self.0.borrow().viewer_elem.client_width());
|
|
1062
|
+
let new_height = format!("{}px", self.0.borrow().viewer_elem.client_height());
|
|
1053
1063
|
main_panel.style().set_property("width", &new_width)?;
|
|
1054
1064
|
main_panel.style().set_property("height", &new_height)?;
|
|
1055
1065
|
let result = plugin.resize().await;
|
|
@@ -95,6 +95,16 @@ impl SessionMetadata {
|
|
|
95
95
|
Ok(())
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/// Whether `view_schema` has been populated by a prior successful
|
|
99
|
+
/// `create_view`. Used by `Session::create_view` to force a full
|
|
100
|
+
/// build on first run even when `is_clean` happens to be true, so
|
|
101
|
+
/// that downstream consumers (`query_column_config_schema`,
|
|
102
|
+
/// strip-on-write in `update_columns_configs`) always see a real
|
|
103
|
+
/// view schema rather than `None`.
|
|
104
|
+
pub fn has_view_schema(&self) -> bool {
|
|
105
|
+
self.as_ref().and_then(|s| s.view_schema.as_ref()).is_some()
|
|
106
|
+
}
|
|
107
|
+
|
|
98
108
|
pub(super) fn update_expressions(
|
|
99
109
|
&mut self,
|
|
100
110
|
valid_recs: &perspective_client::ExprValidationResult,
|
|
@@ -302,7 +312,7 @@ impl SessionMetadata {
|
|
|
302
312
|
Some(
|
|
303
313
|
self.get_expression_columns()
|
|
304
314
|
.cloned()
|
|
305
|
-
.chain(self.get_table_columns()?.clone()
|
|
315
|
+
.chain(self.get_table_columns()?.clone())
|
|
306
316
|
.map(move |name| {
|
|
307
317
|
self.get_column_table_type(&name)
|
|
308
318
|
.map(|coltype| (name, coltype))
|
package/src/rust/session.rs
CHANGED
|
@@ -760,7 +760,20 @@ impl ValidSession<'_> {
|
|
|
760
760
|
/// `update()` subscription, consuming this `ValidSession<'_>` and returning
|
|
761
761
|
/// the original `&Session`.
|
|
762
762
|
pub async fn create_view(&self) -> Result<Option<View>, ApiError> {
|
|
763
|
-
|
|
763
|
+
// Always consume `is_clean` to preserve the "mark up-to-date"
|
|
764
|
+
// contract of `reset_clean`. Force a full build if no view
|
|
765
|
+
// schema has been built yet — `query_column_config_schema` (and
|
|
766
|
+
// downstream `update_columns_configs`) needs a populated
|
|
767
|
+
// `view_schema` to avoid destructively stripping every key from
|
|
768
|
+
// incoming `columns_config` payloads. Without this fallback, a
|
|
769
|
+
// first restore that lands with `is_clean = true` (e.g., when a
|
|
770
|
+
// prior validate already consumed the flag) would skip the
|
|
771
|
+
// view-schema-building inner block, leaving the schema empty
|
|
772
|
+
// and causing strip-on-write to silently zero out
|
|
773
|
+
// user-supplied column config.
|
|
774
|
+
let was_clean = self.0.reset_clean();
|
|
775
|
+
let needs_schema = !self.0.metadata().has_view_schema();
|
|
776
|
+
if (!was_clean && !self.0.borrow().is_paused) || needs_schema {
|
|
764
777
|
if !self.1 {
|
|
765
778
|
let config = self.0.borrow().config.clone();
|
|
766
779
|
if let Some(sub) = &mut self.0.borrow_mut().view_sub.as_mut() {
|
package/src/themes/botanical.css
CHANGED
|
@@ -33,6 +33,7 @@ perspective-viewer[theme="Botanical"] {
|
|
|
33
33
|
--psp-expression--function--color: #7bc96f;
|
|
34
34
|
--psp-expression--psp-error--color: rgb(232, 131, 106);
|
|
35
35
|
--psp-calendar--filter: invert(1);
|
|
36
|
+
--psp-input--filter: invert(1);
|
|
36
37
|
--psp-warning--color: #1a2e1a;
|
|
37
38
|
--psp-warning--background: var(--psp--color);
|
|
38
39
|
|
|
@@ -110,6 +111,7 @@ perspective-string-column-style[theme="Botanical"] {
|
|
|
110
111
|
--psp-expression--function--color: #7bc96f;
|
|
111
112
|
--psp-expression--psp-error--color: rgb(232, 131, 106);
|
|
112
113
|
--psp-calendar--filter: invert(1);
|
|
114
|
+
--psp-input--filter: invert(1);
|
|
113
115
|
--psp-warning--color: #1a2e1a;
|
|
114
116
|
--psp-warning--background: var(--psp--color);
|
|
115
117
|
|
package/src/themes/dracula.css
CHANGED
|
@@ -32,6 +32,7 @@ perspective-viewer[theme="Dracula"] {
|
|
|
32
32
|
--psp-expression--function--color: #22a0ce;
|
|
33
33
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
34
34
|
--psp-calendar--filter: invert(1);
|
|
35
|
+
--psp-input--filter: invert(1);
|
|
35
36
|
--psp-warning--color: #242526;
|
|
36
37
|
--psp-warning--background: var(--psp--color);
|
|
37
38
|
|
|
@@ -170,6 +171,7 @@ perspective-dropdown[theme="Dracula"] {
|
|
|
170
171
|
--psp-expression--function--color: #22a0ce;
|
|
171
172
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
172
173
|
--psp-calendar--filter: invert(1);
|
|
174
|
+
--psp-input--filter: invert(1);
|
|
173
175
|
--psp-warning--color: #242526;
|
|
174
176
|
--psp-warning--background: var(--psp--color);
|
|
175
177
|
--psp-icon--select-arrow--mask-image: var(
|
|
@@ -32,6 +32,7 @@ perspective-viewer[theme="Gruvbox Dark"] {
|
|
|
32
32
|
--psp-expression--function--color: #22a0ce;
|
|
33
33
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
34
34
|
--psp-calendar--filter: invert(1);
|
|
35
|
+
--psp-input--filter: invert(1);
|
|
35
36
|
--psp-warning--color: #242526;
|
|
36
37
|
--psp-warning--background: var(--psp--color);
|
|
37
38
|
|
|
@@ -183,6 +184,7 @@ perspective-dropdown[theme="Gruvbox Dark"] {
|
|
|
183
184
|
--psp-expression--function--color: #22a0ce;
|
|
184
185
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
185
186
|
--psp-calendar--filter: invert(1);
|
|
187
|
+
--psp-input--filter: invert(1);
|
|
186
188
|
--psp-warning--color: #242526;
|
|
187
189
|
--psp-warning--background: var(--psp--color);
|
|
188
190
|
--psp-icon--select-arrow--mask-image: var(
|
package/src/themes/monokai.css
CHANGED
|
@@ -32,6 +32,7 @@ perspective-viewer[theme="Monokai"] {
|
|
|
32
32
|
--psp-expression--function--color: #22a0ce;
|
|
33
33
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
34
34
|
--psp-calendar--filter: invert(1);
|
|
35
|
+
--psp-input--filter: invert(1);
|
|
35
36
|
--psp-warning--color: #242526;
|
|
36
37
|
--psp-warning--background: var(--psp--color);
|
|
37
38
|
|
|
@@ -183,6 +184,7 @@ perspective-string-column-style[theme="Monokai"] {
|
|
|
183
184
|
--psp-expression--function--color: #22a0ce;
|
|
184
185
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
185
186
|
--psp-calendar--filter: invert(1);
|
|
187
|
+
--psp-input--filter: invert(1);
|
|
186
188
|
--psp-warning--color: #242526;
|
|
187
189
|
--psp-warning--background: var(--psp--color);
|
|
188
190
|
--psp-icon--select-arrow--mask-image: var(
|
package/src/themes/phosphor.css
CHANGED
|
@@ -43,6 +43,7 @@ perspective-viewer[theme="Phosphor"] {
|
|
|
43
43
|
--psp-expression--function--color: var(--theme-green-bright);
|
|
44
44
|
--psp-expression--psp-error--color: var(--theme-red);
|
|
45
45
|
--psp-calendar--filter: invert(1) hue-rotate(70deg);
|
|
46
|
+
--psp-input--filter: invert(1) hue-rotate(70deg);
|
|
46
47
|
--psp-warning--color: var(--theme-bg0);
|
|
47
48
|
--psp-warning--background: var(--theme-amber);
|
|
48
49
|
|
|
@@ -153,6 +154,7 @@ perspective-string-column-style[theme="Phosphor"] {
|
|
|
153
154
|
--psp-expression--function--color: var(--theme-green-bright);
|
|
154
155
|
--psp-expression--psp-error--color: var(--theme-red);
|
|
155
156
|
--psp-calendar--filter: invert(1) hue-rotate(70deg);
|
|
157
|
+
--psp-input--filter: invert(1) hue-rotate(70deg);
|
|
156
158
|
--psp-warning--color: var(--theme-bg0);
|
|
157
159
|
--psp-warning--background: var(--theme-amber);
|
|
158
160
|
--psp-icon--select-arrow--mask-image: var(
|
package/src/themes/pro-dark.css
CHANGED
|
@@ -33,6 +33,7 @@ perspective-viewer[theme="Pro Dark"] {
|
|
|
33
33
|
--psp-expression--function--color: #22a0ce;
|
|
34
34
|
--psp-expression--error--color: rgb(255, 136, 136);
|
|
35
35
|
--psp-calendar--filter: invert(1);
|
|
36
|
+
--psp-input--filter: invert(1);
|
|
36
37
|
--psp-warning--color: #242526;
|
|
37
38
|
--psp-warning--background: var(--psp--color);
|
|
38
39
|
|
|
@@ -127,6 +128,7 @@ perspective-string-column-style[theme="Pro Dark"] {
|
|
|
127
128
|
--psp-expression--function--color: #22a0ce;
|
|
128
129
|
--psp-expression--error--color: rgb(255, 136, 136);
|
|
129
130
|
--psp-calendar--filter: invert(1);
|
|
131
|
+
--psp-input--filter: invert(1);
|
|
130
132
|
--psp-warning--color: #242526;
|
|
131
133
|
--psp-warning--background: var(--psp--color);
|
|
132
134
|
|
package/src/themes/vaporwave.css
CHANGED
|
@@ -32,6 +32,7 @@ perspective-viewer[theme="Vaporwave"] {
|
|
|
32
32
|
--psp-expression--function--color: #22a0ce;
|
|
33
33
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
34
34
|
--psp-calendar--filter: invert(1);
|
|
35
|
+
--psp-input--filter: invert(1);
|
|
35
36
|
--psp-warning--color: #242526;
|
|
36
37
|
--psp-warning--background: var(--psp--color);
|
|
37
38
|
|
|
@@ -195,6 +196,7 @@ perspective-string-column-style[theme="Vaporwave"] {
|
|
|
195
196
|
--psp-expression--function--color: #22a0ce;
|
|
196
197
|
--psp-expression--psp-error--color: rgb(255, 136, 136);
|
|
197
198
|
--psp-calendar--filter: invert(1);
|
|
199
|
+
--psp-input--filter: invert(1);
|
|
198
200
|
--psp-warning--color: #242526;
|
|
199
201
|
--psp-warning--background: var(--psp--color);
|
|
200
202
|
--psp-icon--select-arrow--mask-image: var(
|
package/tsconfig.json
CHANGED