@perspective-dev/viewer 5.2.0 → 5.3.1

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.
Files changed (179) hide show
  1. package/dist/cdn/perspective-viewer.js +8 -8
  2. package/dist/cdn/perspective-viewer.js.map +3 -3
  3. package/dist/css/blueprint.css +1 -0
  4. package/dist/css/botanical.css +1 -1
  5. package/dist/css/dracula.css +1 -1
  6. package/dist/css/eggplant.css +1 -0
  7. package/dist/css/gruvbox-dark.css +1 -1
  8. package/dist/css/gruvbox.css +1 -1
  9. package/dist/css/icons.css +1 -1
  10. package/dist/css/intl/de.css +1 -1
  11. package/dist/css/intl/es.css +1 -1
  12. package/dist/css/intl/fr.css +1 -1
  13. package/dist/css/intl/ja.css +1 -1
  14. package/dist/css/intl/pt.css +1 -1
  15. package/dist/css/intl/zh.css +1 -1
  16. package/dist/css/intl.css +1 -1
  17. package/dist/css/ledger.css +1 -0
  18. package/dist/css/monokai.css +1 -1
  19. package/dist/css/nord.css +1 -0
  20. package/dist/css/phosphor.css +1 -1
  21. package/dist/css/pro-dark.css +1 -1
  22. package/dist/css/pro.css +1 -1
  23. package/dist/css/solarized-dark.css +1 -1
  24. package/dist/css/solarized.css +1 -1
  25. package/dist/css/themes.css +1 -1
  26. package/dist/css/vaporwave.css +1 -1
  27. package/dist/css/velvet.css +1 -0
  28. package/dist/docs/perspective-docs.json +1 -1
  29. package/dist/esm/column-format.d.ts +16 -3
  30. package/dist/esm/perspective-viewer.d.ts +1 -0
  31. package/dist/esm/perspective-viewer.inline.js +9 -9
  32. package/dist/esm/perspective-viewer.inline.js.map +3 -3
  33. package/dist/esm/perspective-viewer.js +8 -8
  34. package/dist/esm/perspective-viewer.js.map +3 -3
  35. package/dist/esm/plugin.d.ts +10 -0
  36. package/dist/esm/ts-rs/PanelViewerConfig.d.ts +1 -1
  37. package/dist/esm/ts-rs/SaveWorkspaceOptions.d.ts +10 -0
  38. package/dist/esm/ts-rs/ViewerConfig.d.ts +1 -1
  39. package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
  40. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +13 -3
  41. package/dist/wasm/perspective-viewer.d.ts +43 -36
  42. package/dist/wasm/perspective-viewer.js +198 -136
  43. package/dist/wasm/perspective-viewer.wasm +0 -0
  44. package/dist/wasm/perspective-viewer.wasm.d.ts +19 -17
  45. package/package.json +1 -1
  46. package/src/css/column-settings-panel.css +28 -5
  47. package/src/css/column-style.css +291 -31
  48. package/src/css/containers/tabs.css +13 -3
  49. package/src/css/dom/select.css +21 -9
  50. package/src/css/form/code-editor.css +4 -4
  51. package/src/css/plugin-selector.css +1 -0
  52. package/src/css/plugin-settings-panel.css +72 -0
  53. package/src/css/viewer.css +0 -5
  54. package/src/rust/agent/tools.rs +53 -19
  55. package/src/rust/components/column_selector/active_column.rs +2 -2
  56. package/src/rust/components/column_selector/add_expression_button.rs +3 -3
  57. package/src/rust/components/column_selector/aggregate_selector.rs +2 -3
  58. package/src/rust/components/column_selector/config_selector.rs +8 -0
  59. package/src/rust/components/column_selector/expr_edit_button.rs +4 -10
  60. package/src/rust/components/column_selector/inactive_column.rs +2 -2
  61. package/src/rust/components/column_selector.rs +48 -4
  62. package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +293 -126
  63. package/src/rust/components/column_settings_sidebar/style_tab.rs +330 -234
  64. package/src/rust/components/column_settings_sidebar.rs +88 -69
  65. package/src/rust/components/containers/control_group.rs +91 -0
  66. package/src/rust/components/containers/mod.rs +1 -0
  67. package/src/rust/components/containers/select.rs +8 -2
  68. package/src/rust/components/datetime_column_style/simple.rs +15 -4
  69. package/src/rust/components/datetime_column_style.rs +50 -10
  70. package/src/rust/components/editable_header.rs +85 -144
  71. package/src/rust/components/expression_editor.rs +9 -16
  72. package/src/rust/components/form/code_editor.rs +16 -6
  73. package/src/rust/components/form/debug.rs +1 -0
  74. package/src/rust/components/form/mod.rs +3 -1
  75. package/src/rust/components/form/multi_stop_gradient_selector.rs +476 -0
  76. package/src/rust/components/form/named_value_picker.rs +86 -0
  77. package/src/rust/components/form/palette_selector.rs +440 -0
  78. package/src/rust/components/main_panel/msg.rs +2 -2
  79. package/src/rust/components/main_panel/reconcile.rs +4 -4
  80. package/src/rust/components/plugin_tab.rs +126 -112
  81. package/src/rust/components/settings_panel.rs +26 -20
  82. package/src/rust/components/status_bar.rs +0 -1
  83. package/src/rust/components/style_controls/number_string_format/digits_section.rs +22 -10
  84. package/src/rust/components/style_controls/number_string_format/misc_section.rs +6 -2
  85. package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -0
  86. package/src/rust/components/style_controls/number_string_format/types.rs +24 -0
  87. package/src/rust/components/style_controls/number_string_format.rs +37 -14
  88. package/src/rust/components/viewer/msg.rs +46 -7
  89. package/src/rust/components/viewer/panels.rs +11 -9
  90. package/src/rust/components/viewer/render.rs +8 -3
  91. package/src/rust/components/viewer/settings.rs +163 -23
  92. package/src/rust/components/viewer/snapshots.rs +46 -21
  93. package/src/rust/components/viewer/wiring.rs +14 -25
  94. package/src/rust/components/viewer.rs +12 -8
  95. package/src/rust/config/column_config_schema.rs +435 -45
  96. package/src/rust/config/css_scale.rs +882 -0
  97. package/src/rust/config/datetime_column_style.rs +4 -21
  98. package/src/rust/config/mod.rs +2 -0
  99. package/src/rust/config/number_string_format.rs +211 -18
  100. package/src/rust/config/options.rs +10 -0
  101. package/src/rust/config/viewer_config.rs +49 -55
  102. package/src/rust/config/workspace_config.rs +132 -5
  103. package/src/rust/custom_elements/viewer.rs +214 -155
  104. package/src/rust/custom_events.rs +14 -1
  105. package/src/rust/js/regular_layout.rs +3 -3
  106. package/src/rust/lib.rs +2 -0
  107. package/src/rust/presentation/column_locator.rs +19 -5
  108. package/src/rust/presentation.rs +209 -36
  109. package/src/rust/queries/column_locator.rs +74 -44
  110. package/src/rust/queries/get_viewer_config.rs +0 -3
  111. package/src/rust/queries/mod.rs +2 -0
  112. package/src/rust/queries/palette_set.rs +82 -0
  113. package/src/rust/queries/plugin_column_styles.rs +6 -2
  114. package/src/rust/renderer/dispatch.rs +50 -12
  115. package/src/rust/renderer/plugin_config.rs +362 -53
  116. package/src/rust/renderer.rs +15 -42
  117. package/src/rust/session/column_defaults_update.rs +15 -8
  118. package/src/rust/session/metadata.rs +5 -1
  119. package/src/rust/session/props.rs +1 -0
  120. package/src/rust/session.rs +9 -6
  121. package/src/rust/tasks/create_panel.rs +44 -57
  122. package/src/rust/tasks/edit_expression.rs +19 -23
  123. package/src/rust/tasks/edit_window.rs +8 -10
  124. package/src/rust/tasks/eject.rs +4 -1
  125. package/src/rust/tasks/pipeline.rs +2 -2
  126. package/src/rust/tasks/presize_panels.rs +44 -5
  127. package/src/rust/tasks/reset_all.rs +4 -4
  128. package/src/rust/tasks/restore_and_render.rs +17 -44
  129. package/src/rust/tasks/restore_panel.rs +11 -13
  130. package/src/rust/tasks/set_edit_mode.rs +3 -1
  131. package/src/rust/tasks/sync_update_panels.rs +11 -1
  132. package/src/rust/tasks/update_theme.rs +23 -18
  133. package/src/rust/utils/css_vars.rs +26 -0
  134. package/src/rust/utils/mod.rs +2 -0
  135. package/src/rust/utils/spawn.rs +1 -1
  136. package/src/rust/workspace.rs +435 -272
  137. package/src/svg/lock.svg +7 -0
  138. package/src/themes/blueprint.css +190 -0
  139. package/src/themes/botanical.css +14 -17
  140. package/src/themes/defaults.css +4 -110
  141. package/src/themes/dracula.css +19 -14
  142. package/src/themes/eggplant.css +189 -0
  143. package/src/themes/gruvbox-dark.css +23 -15
  144. package/src/themes/gruvbox.css +11 -1
  145. package/src/themes/icons.css +2 -2
  146. package/src/themes/intl/de.css +23 -1
  147. package/src/themes/intl/es.css +23 -1
  148. package/src/themes/intl/fr.css +23 -1
  149. package/src/themes/intl/ja.css +23 -1
  150. package/src/themes/intl/pt.css +23 -1
  151. package/src/themes/intl/zh.css +23 -1
  152. package/src/themes/intl.css +26 -4
  153. package/src/themes/ledger.css +195 -0
  154. package/src/themes/monokai.css +24 -14
  155. package/src/themes/nord.css +186 -0
  156. package/src/themes/phosphor.css +7 -14
  157. package/src/themes/pro-dark.css +12 -16
  158. package/src/themes/pro.css +118 -0
  159. package/src/themes/solarized-dark.css +9 -16
  160. package/src/themes/solarized.css +7 -0
  161. package/src/themes/themes.css +10 -5
  162. package/src/themes/vaporwave.css +22 -14
  163. package/src/themes/velvet.css +192 -0
  164. package/src/ts/column-format.ts +52 -2
  165. package/src/ts/perspective-viewer.ts +1 -0
  166. package/src/ts/plugin.ts +14 -0
  167. package/src/ts/ts-rs/PanelViewerConfig.ts +1 -1
  168. package/src/ts/ts-rs/SaveWorkspaceOptions.ts +11 -0
  169. package/src/ts/ts-rs/ViewerConfig.ts +1 -1
  170. package/src/ts/ts-rs/WorkspaceConfig.ts +8 -2
  171. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +11 -3
  172. package/src/rust/components/form/color_range_selector.rs +0 -137
  173. package/src/svg/dropdown-selector-light.svg +0 -3
  174. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline0.js +0 -0
  175. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline1.js +0 -0
  176. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline2.js +0 -0
  177. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline3.js +0 -0
  178. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline4.js +0 -0
  179. /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline5.js +0 -0
@@ -14,32 +14,30 @@ use std::rc::Rc;
14
14
 
15
15
  use itertools::Itertools;
16
16
  use web_sys::{FocusEvent, HtmlInputElement, KeyboardEvent};
17
- use yew::{Callback, Component, Html, NodeRef, Properties, TargetCast, classes, html};
17
+ use yew::prelude::*;
18
18
 
19
19
  use super::type_icon::TypeIconType;
20
20
  use crate::components::type_icon::TypeIcon;
21
- use crate::session::{Session, SessionMetadataRc};
21
+ use crate::session::SessionMetadataRc;
22
22
 
23
23
  #[derive(Clone, PartialEq, Properties)]
24
24
  pub struct EditableHeaderProps {
25
25
  pub icon_type: Option<TypeIconType>,
26
26
  pub on_change: Callback<(Option<String>, bool)>,
27
27
  pub editable: bool,
28
+
29
+ /// The owner's draft.
30
+ pub value: Option<String>,
31
+
32
+ /// The saved name the draft is measured against.
28
33
  pub initial_value: Option<String>,
29
34
  pub placeholder: Rc<String>,
30
35
 
31
- // TODO remove this pattern
32
- #[prop_or_default]
33
- pub reset_count: u8,
34
-
35
36
  #[prop_or_default]
36
37
  pub update_on_input: bool,
37
38
 
38
39
  /// Session metadata snapshot — threaded from `SessionProps`.
39
40
  pub metadata: SessionMetadataRc,
40
-
41
- // State
42
- pub session: Session,
43
41
  }
44
42
 
45
43
  impl EditableHeaderProps {
@@ -55,152 +53,95 @@ impl EditableHeaderProps {
55
53
  Some((idx, _)) => split[..idx].to_owned(),
56
54
  }
57
55
  }
58
- }
59
-
60
- pub enum EditableHeaderMsg {
61
- SetNewValue(String),
62
- OnClick(()),
63
- }
64
56
 
65
- #[derive(Debug)]
66
- pub struct EditableHeader {
67
- noderef: NodeRef,
68
- edited: bool,
69
- valid: bool,
70
- value: Option<String>,
71
- placeholder: String,
72
- }
57
+ fn is_valid(&self, value: &Option<String>, placeholder: &str) -> bool {
58
+ let Some(value) = value else {
59
+ return true;
60
+ };
73
61
 
74
- impl Component for EditableHeader {
75
- type Message = EditableHeaderMsg;
76
- type Properties = EditableHeaderProps;
77
-
78
- fn create(ctx: &yew::prelude::Context<Self>) -> Self {
79
- Self {
80
- value: ctx.props().initial_value.clone(),
81
- placeholder: ctx.props().split_placeholder(),
82
- valid: true,
83
- noderef: NodeRef::default(),
84
- edited: false,
62
+ if value == placeholder || Some(value) == self.initial_value.as_ref() {
63
+ return true;
85
64
  }
86
- }
87
65
 
88
- fn changed(&mut self, ctx: &yew::prelude::Context<Self>, old_props: &Self::Properties) -> bool {
89
- if ctx.props().reset_count != old_props.reset_count {
90
- self.value.clone_from(&ctx.props().initial_value);
91
- }
92
- if ctx.props().initial_value != old_props.initial_value {
93
- self.edited = false;
94
- self.value.clone_from(&ctx.props().initial_value);
95
- }
96
- if !ctx.props().editable {
97
- self.edited = false;
98
- }
99
- self.placeholder = ctx.props().split_placeholder();
100
- ctx.props() != old_props
101
- }
66
+ let metadata = &self.metadata;
67
+ let Some(table_columns) = metadata.get_table_columns() else {
68
+ return true;
69
+ };
102
70
 
103
- fn update(&mut self, ctx: &yew::prelude::Context<Self>, msg: Self::Message) -> bool {
104
- match msg {
105
- EditableHeaderMsg::SetNewValue(new_value) => {
106
- let maybe_value = (!new_value.is_empty()).then_some(new_value.clone());
107
- self.edited = ctx.props().initial_value != maybe_value;
108
-
109
- self.valid = (|| -> Option<bool> {
110
- if maybe_value
111
- .as_ref()
112
- .map(|v| v == &self.placeholder)
113
- .unwrap_or(true)
114
- {
115
- return Some(true);
116
- }
117
- if !self.edited {
118
- return Some(true);
119
- }
120
- let metadata = &ctx.props().metadata;
121
- let expressions = metadata.get_expression_columns();
122
- let windows = metadata.get_window_columns();
123
- let found = metadata
124
- .get_table_columns()?
125
- .iter()
126
- .chain(expressions)
127
- .chain(windows)
128
- .contains(&new_value);
129
- Some(!found)
130
- })()
131
- .unwrap_or(true);
132
-
133
- self.value.clone_from(&maybe_value);
134
- ctx.props().on_change.emit((maybe_value, self.valid));
135
- true
136
- },
137
- EditableHeaderMsg::OnClick(()) => {
138
- self.noderef
139
- .cast::<HtmlInputElement>()
140
- .unwrap()
141
- .focus()
142
- .unwrap();
143
- false
144
- },
145
- }
71
+ !table_columns
72
+ .iter()
73
+ .chain(metadata.get_expression_columns())
74
+ .chain(metadata.get_window_columns())
75
+ .contains(value)
146
76
  }
77
+ }
147
78
 
148
- fn view(&self, ctx: &yew::prelude::Context<Self>) -> Html {
149
- let mut classes = classes!("sidebar_header_contents");
150
- if ctx.props().editable {
151
- classes.push("editable");
152
- }
153
-
154
- if !self.valid {
155
- classes.push("invalid");
156
- }
157
-
158
- if self.edited {
159
- classes.push("edited");
160
- }
79
+ #[function_component(EditableHeader)]
80
+ pub fn editable_header(props: &EditableHeaderProps) -> Html {
81
+ let noderef = use_node_ref();
82
+ let placeholder = props.split_placeholder();
83
+ let edited = props.value != props.initial_value;
84
+ let valid = props.is_valid(&props.value, &placeholder);
85
+ let mut classes = classes!("sidebar_header_contents");
86
+ if props.editable {
87
+ classes.push("editable");
88
+ }
161
89
 
162
- let onkeyup = ctx.link().callback(|e: KeyboardEvent| {
163
- let value = e.target_unchecked_into::<HtmlInputElement>().value();
164
- EditableHeaderMsg::SetNewValue(value)
165
- });
90
+ if !valid {
91
+ classes.push("invalid");
92
+ }
166
93
 
167
- let onblur = ctx.link().callback(|e: FocusEvent| {
168
- let value = e.target_unchecked_into::<HtmlInputElement>().value();
169
- EditableHeaderMsg::SetNewValue(value)
170
- });
94
+ if edited {
95
+ classes.push("edited");
96
+ }
171
97
 
172
- let update_on_input = ctx.props().update_on_input;
173
- let oninput = ctx.link().batch_callback(move |e: yew::InputEvent| {
98
+ let on_value = {
99
+ let props = props.clone();
100
+ let placeholder = placeholder.clone();
101
+ Callback::from(move |value: String| {
102
+ let value = (!value.is_empty()).then_some(value);
103
+ let valid = props.is_valid(&value, &placeholder);
104
+ props.on_change.emit((value, valid));
105
+ })
106
+ };
107
+
108
+ let onkeyup =
109
+ on_value.reform(|e: KeyboardEvent| e.target_unchecked_into::<HtmlInputElement>().value());
110
+ let onblur =
111
+ on_value.reform(|e: FocusEvent| e.target_unchecked_into::<HtmlInputElement>().value());
112
+ let oninput = {
113
+ let update_on_input = props.update_on_input;
114
+ let on_value = on_value.clone();
115
+ Callback::from(move |e: InputEvent| {
174
116
  if update_on_input {
175
- let value = e.target_unchecked_into::<HtmlInputElement>().value();
176
- vec![EditableHeaderMsg::SetNewValue(value)]
177
- } else {
178
- vec![]
117
+ on_value.emit(e.target_unchecked_into::<HtmlInputElement>().value());
179
118
  }
180
- });
181
-
182
- html! {
183
- <div class={classes} onclick={ctx.link().callback(|_| EditableHeaderMsg::OnClick(()))}>
184
- if let Some(icon) = ctx.props().icon_type { <TypeIcon ty={icon} /> }
185
- <input
186
- ref={self.noderef.clone()}
187
- type="search"
188
- class="sidebar_header_title"
189
- disabled={!ctx.props().editable}
190
- {onblur}
191
- {onkeyup}
192
- {oninput}
193
- value={self.value.clone()}
194
- placeholder={self.placeholder.clone()}
195
- />
196
- </div>
197
- }
119
+ })
120
+ };
121
+
122
+ let onclick = {
123
+ let noderef = noderef.clone();
124
+ Callback::from(move |_: MouseEvent| {
125
+ if let Some(input) = noderef.cast::<HtmlInputElement>() {
126
+ let _ = input.focus();
127
+ }
128
+ })
129
+ };
130
+
131
+ html! {
132
+ <div class={classes} {onclick}>
133
+ if let Some(icon) = props.icon_type { <TypeIcon ty={icon} /> }
134
+ <input
135
+ ref={noderef}
136
+ type="search"
137
+ class="sidebar_header_title"
138
+ disabled={!props.editable}
139
+ {onblur}
140
+ {onkeyup}
141
+ {oninput}
142
+ value={props.value.clone()}
143
+ {placeholder}
144
+ />
145
+ </div>
198
146
  }
199
147
  }
200
-
201
- #[derive(Default, Debug, PartialEq, Copy, Clone)]
202
- pub enum ValueState {
203
- #[default]
204
- Unedited,
205
- Edited,
206
- }
@@ -16,7 +16,7 @@ use perspective_client::{ExprValidationError, clone};
16
16
  use yew::prelude::*;
17
17
 
18
18
  use super::form::code_editor::*;
19
- use crate::session::{Session, SessionMetadata, SessionMetadataRc};
19
+ use crate::session::{Session, SessionMetadataRc};
20
20
  use crate::tasks::{ExprValidation, validate_expression};
21
21
 
22
22
  #[derive(Properties, PartialEq, Clone)]
@@ -27,6 +27,9 @@ pub struct ExpressionEditorProps {
27
27
  pub alias: Option<String>,
28
28
  pub disabled: bool,
29
29
 
30
+ /// The saved expression text this editor edits against.
31
+ pub initial_expr: Rc<String>,
32
+
30
33
  #[prop_or_default]
31
34
  pub reset_count: u8,
32
35
 
@@ -69,7 +72,7 @@ impl Component for ExpressionEditor {
69
72
 
70
73
  fn create(ctx: &Context<Self>) -> Self {
71
74
  let oninput = ctx.link().callback(ExpressionEditorMsg::SetExpr);
72
- let expr = initial_expr(&ctx.props().metadata, &ctx.props().alias);
75
+ let expr = ctx.props().initial_expr.clone();
73
76
  ctx.link()
74
77
  .send_message(Self::Message::SetExpr(expr.clone()));
75
78
 
@@ -156,24 +159,14 @@ impl Component for ExpressionEditor {
156
159
  fn changed(&mut self, ctx: &Context<Self>, old_props: &Self::Properties) -> bool {
157
160
  if ctx.props().alias != old_props.alias
158
161
  || ctx.props().reset_count != old_props.reset_count
159
- || (ctx.props().alias.is_some() && ctx.props().metadata != old_props.metadata)
162
+ || ctx.props().initial_expr != old_props.initial_expr
160
163
  {
161
- ctx.link()
162
- .send_message(ExpressionEditorMsg::SetExpr(initial_expr(
163
- &ctx.props().metadata,
164
- &ctx.props().alias,
165
- )));
164
+ ctx.link().send_message(ExpressionEditorMsg::SetExpr(
165
+ ctx.props().initial_expr.clone(),
166
+ ));
166
167
  false
167
168
  } else {
168
169
  true
169
170
  }
170
171
  }
171
172
  }
172
-
173
- fn initial_expr(metadata: &SessionMetadata, alias: &Option<String>) -> Rc<String> {
174
- alias
175
- .as_ref()
176
- .and_then(|alias| metadata.get_expression_by_alias(alias))
177
- .unwrap_or_default()
178
- .into()
179
- }
@@ -45,6 +45,9 @@ pub struct CodeEditorProps {
45
45
  #[prop_or_default]
46
46
  pub error: Option<ExprValidationError>,
47
47
 
48
+ #[prop_or_default]
49
+ pub contained: bool,
50
+
48
51
  /// Selected theme name, threaded for PortalModal consumers.
49
52
  #[prop_or_default]
50
53
  pub theme: String,
@@ -165,20 +168,27 @@ pub fn code_editor(props: &CodeEditorProps) -> Html {
165
168
  ))
166
169
  .collect::<Html>();
167
170
 
168
- let class = if props.wordwrap {
169
- "wordwrap scrollable"
170
- } else {
171
- "scrollable"
171
+ let mut outer_class = classes!("scrollable");
172
+ let mut inner_class = classes!("editor-inner", "scrollable");
173
+
174
+ if props.wordwrap {
175
+ outer_class.push("wordwrap");
176
+ inner_class.push("wordwrap");
172
177
  };
178
+
179
+ if props.contained {
180
+ outer_class.push("contained")
181
+ }
182
+
173
183
  clone!(props.disabled);
174
184
  html! {
175
185
  <>
176
- <div id="editor" {class}>
186
+ <div id="editor" class={outer_class}>
177
187
  <div id="line_numbers" ref={lineno_ref}>{ line_numbers }</div>
178
188
  <MirroredTextarea
179
189
  id="textarea_editable"
180
190
  mirror_id="content"
181
- class={classes!("editor-inner", class)}
191
+ class={inner_class}
182
192
  mirror={terms}
183
193
  {textarea_ref}
184
194
  mirror_ref={content_ref}
@@ -178,6 +178,7 @@ pub fn debug_panel(props: &DebugPanelProps) -> Html {
178
178
  <CodeEditor
179
179
  expr={&*expr}
180
180
  disabled=false
181
+ contained=true
181
182
  {oninput}
182
183
  {onsave}
183
184
  select_all={select_all.subscriber()}
@@ -17,14 +17,16 @@
17
17
  //! parent module directly.
18
18
 
19
19
  pub mod code_editor;
20
- pub mod color_range_selector;
21
20
  pub mod color_selector;
22
21
  pub mod debug;
23
22
  pub mod mirrored_textarea;
23
+ pub mod multi_stop_gradient_selector;
24
+ pub mod named_value_picker;
24
25
  pub mod number_field;
25
26
  pub mod number_input;
26
27
  pub mod number_range_field;
27
28
  pub mod optional_field;
29
+ pub mod palette_selector;
28
30
  pub mod select_enum_field;
29
31
  pub mod select_value_field;
30
32