@perspective-dev/viewer 5.3.1 → 5.5.0

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 (291) hide show
  1. package/dist/cdn/perspective-viewer.js +6 -6
  2. package/dist/cdn/perspective-viewer.js.map +2 -2
  3. package/dist/css/blueprint.css +1 -1
  4. package/dist/css/botanical.css +1 -1
  5. package/dist/css/dracula.css +1 -1
  6. package/dist/css/eggplant.css +1 -1
  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/ar.css +1 -0
  11. package/dist/css/intl/de.css +1 -1
  12. package/dist/css/intl/es.css +1 -1
  13. package/dist/css/intl/fr.css +1 -1
  14. package/dist/css/intl/ja.css +1 -1
  15. package/dist/css/intl/pt.css +1 -1
  16. package/dist/css/intl/zh.css +1 -1
  17. package/dist/css/intl.css +1 -1
  18. package/dist/css/ledger.css +1 -1
  19. package/dist/css/monokai.css +1 -1
  20. package/dist/css/nord.css +1 -1
  21. package/dist/css/phosphor.css +1 -1
  22. package/dist/css/pro-dark.css +1 -1
  23. package/dist/css/pro.css +1 -1
  24. package/dist/css/solarized-dark.css +1 -1
  25. package/dist/css/solarized.css +1 -1
  26. package/dist/css/themes.css +1 -1
  27. package/dist/css/vaporwave.css +1 -1
  28. package/dist/css/velvet.css +1 -1
  29. package/dist/docs/perspective-docs.json +1 -1
  30. package/dist/esm/extensions.d.ts +0 -5
  31. package/dist/esm/perspective-viewer.d.ts +2 -0
  32. package/dist/esm/perspective-viewer.inline.js +8 -8
  33. package/dist/esm/perspective-viewer.inline.js.map +2 -2
  34. package/dist/esm/perspective-viewer.js +5 -5
  35. package/dist/esm/perspective-viewer.js.map +2 -2
  36. package/dist/esm/plugin.d.ts +9 -0
  37. package/dist/esm/ts-rs/AddPanelOptions.d.ts +9 -0
  38. package/dist/esm/ts-rs/GetViewMode.d.ts +4 -0
  39. package/dist/esm/ts-rs/GetViewOptions.d.ts +8 -0
  40. package/dist/esm/ts-rs/RestoreOptions.d.ts +6 -0
  41. package/dist/esm/ts-rs/RestoreWorkspaceOptions.d.ts +9 -0
  42. package/dist/esm/ts-rs/ViewOnUpdateResp.d.ts +1 -1
  43. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +30 -22
  44. package/dist/wasm/perspective-viewer.d.ts +137 -104
  45. package/dist/wasm/perspective-viewer.js +337 -269
  46. package/dist/wasm/perspective-viewer.wasm +0 -0
  47. package/dist/wasm/perspective-viewer.wasm.d.ts +20 -30
  48. package/package.json +7 -7
  49. package/src/css/_context_menu.css +1 -1
  50. package/src/css/_dropdown_menu.css +1 -1
  51. package/src/css/_viewer_bundle.css +7 -8
  52. package/src/css/column-dropdown.css +0 -3
  53. package/src/css/column-selector.css +18 -7
  54. package/src/css/column-settings-panel.css +0 -225
  55. package/src/css/column-style.css +175 -0
  56. package/src/css/config-selector.css +19 -11
  57. package/src/css/filter-dropdown.css +5 -5
  58. package/src/css/form/debug.css +37 -4
  59. package/src/css/function-dropdown.css +5 -5
  60. package/src/css/panel-tab.css +23 -0
  61. package/src/css/plugin-selector.css +5 -5
  62. package/src/css/render-warning.css +1 -1
  63. package/src/css/status-bar.css +63 -21
  64. package/src/css/type-icon.css +1 -3
  65. package/src/css/{containers → ui/containers}/context-menu.css +22 -16
  66. package/src/css/ui/containers/dropdown-menu-items.css +66 -0
  67. package/src/css/{containers → ui/containers}/dropdown-menu.css +8 -53
  68. package/src/css/{containers → ui/containers}/tabs.css +2 -1
  69. package/src/css/viewer.css +32 -26
  70. package/src/rust/agent/tools.rs +80 -7
  71. package/src/rust/components/chat_panel.rs +1 -1
  72. package/src/rust/components/{form/code_editor.rs → code_editor.rs} +4 -2
  73. package/src/rust/components/column_dropdown.rs +2 -2
  74. package/src/rust/components/column_selector/active_column.rs +24 -9
  75. package/src/rust/components/column_selector/aggregate_selector.rs +1 -1
  76. package/src/rust/components/column_selector/config_selector.rs +2 -2
  77. package/src/rust/components/column_selector/filter_column.rs +8 -5
  78. package/src/rust/components/column_selector/inactive_column.rs +4 -2
  79. package/src/rust/components/column_selector/pivot_column.rs +4 -3
  80. package/src/rust/components/column_selector/sort_column.rs +7 -4
  81. package/src/rust/components/column_selector.rs +14 -3
  82. package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +1 -1
  83. package/src/rust/components/column_settings_sidebar/style_tab/alignment_field.rs +90 -0
  84. package/src/rust/components/column_settings_sidebar/style_tab/font_field.rs +267 -0
  85. package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +16 -18
  86. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +1 -1
  87. package/src/rust/components/column_settings_sidebar/style_tab.rs +70 -12
  88. package/src/rust/components/column_settings_sidebar.rs +3 -4
  89. package/src/rust/components/copy_dropdown.rs +1 -1
  90. package/src/rust/components/datetime_column_style/custom.rs +1 -3
  91. package/src/rust/components/datetime_column_style/simple.rs +1 -2
  92. package/src/rust/components/datetime_column_style.rs +1 -2
  93. package/src/rust/components/{form/debug.rs → debug_panel.rs} +112 -55
  94. package/src/rust/components/{containers/dragdrop_list.rs → dragdrop_list.rs} +2 -10
  95. package/src/rust/components/export_dropdown.rs +1 -1
  96. package/src/rust/components/expression_editor.rs +1 -1
  97. package/src/rust/components/filter_dropdown.rs +2 -2
  98. package/src/rust/components/function_dropdown.rs +2 -2
  99. package/src/rust/components/main_panel/frame_theme.rs +3 -59
  100. package/src/rust/components/main_panel/msg.rs +4 -0
  101. package/src/rust/components/main_panel/reconcile.rs +9 -4
  102. package/src/rust/components/main_panel/render.rs +62 -11
  103. package/src/rust/components/main_panel/update.rs +39 -10
  104. package/src/rust/components/main_panel.rs +40 -2
  105. package/src/rust/components/mod.rs +5 -8
  106. package/src/rust/components/new_panel_menu.rs +97 -0
  107. package/src/rust/components/number_series_style.rs +2 -3
  108. package/src/rust/components/panel_menu.rs +61 -87
  109. package/src/rust/components/panel_tab.rs +100 -43
  110. package/src/rust/components/plugin_tab.rs +58 -4
  111. package/src/rust/components/render_warning.rs +2 -2
  112. package/src/rust/components/{status_bar_counter.rs → rows_counter.rs} +10 -10
  113. package/src/rust/components/settings_panel.rs +8 -2
  114. package/src/rust/components/status_bar.rs +113 -19
  115. package/src/rust/components/status_indicator.rs +9 -14
  116. package/src/rust/components/{style/mod.rs → style.rs} +32 -15
  117. package/src/rust/components/style_controls/number_string_format/digits_section.rs +3 -5
  118. package/src/rust/components/style_controls/number_string_format/misc_section.rs +1 -1
  119. package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -1
  120. package/src/rust/components/viewer/msg.rs +43 -30
  121. package/src/rust/components/viewer/panels.rs +53 -19
  122. package/src/rust/components/viewer/render.rs +16 -13
  123. package/src/rust/components/viewer/settings.rs +137 -68
  124. package/src/rust/components/viewer/snapshots.rs +5 -10
  125. package/src/rust/components/viewer/wiring.rs +11 -22
  126. package/src/rust/components/viewer.rs +15 -10
  127. package/src/rust/components/window_editor.rs +8 -9
  128. package/src/rust/config/column_config_schema.rs +312 -33
  129. package/src/rust/config/datetime_column_style.rs +0 -11
  130. package/src/rust/config/mod.rs +0 -4
  131. package/src/rust/config/options.rs +50 -0
  132. package/src/rust/config/workspace_config.rs +70 -24
  133. package/src/rust/custom_elements/debug_plugin.rs +1 -10
  134. package/src/rust/custom_elements/mod.rs +0 -3
  135. package/src/rust/custom_elements/viewer.rs +194 -115
  136. package/src/rust/js/plugin.rs +3 -87
  137. package/src/rust/lib.rs +19 -18
  138. package/src/rust/presentation/column_locator.rs +3 -7
  139. package/src/rust/presentation.rs +68 -38
  140. package/src/rust/queries/hosted_tables.rs +38 -0
  141. package/src/rust/queries/mod.rs +2 -0
  142. package/src/rust/queries/palette_set.rs +1 -1
  143. package/src/rust/queries/plugin_column_styles.rs +6 -5
  144. package/src/rust/renderer/activate.rs +1 -3
  145. package/src/rust/renderer/dispatch.rs +83 -22
  146. package/src/rust/renderer/limits.rs +24 -5
  147. package/src/rust/renderer/plugin_config.rs +201 -41
  148. package/src/rust/renderer/plugin_store.rs +2 -1
  149. package/src/rust/renderer/props.rs +7 -1
  150. package/src/rust/renderer.rs +23 -27
  151. package/src/rust/session/props.rs +8 -3
  152. package/src/rust/session/view_subscription.rs +19 -6
  153. package/src/rust/session.rs +189 -150
  154. package/src/rust/tasks/create_panel.rs +5 -2
  155. package/src/rust/tasks/dismiss_render_warning.rs +1 -1
  156. package/src/rust/tasks/eject.rs +1 -0
  157. package/src/rust/tasks/pipeline.rs +18 -67
  158. package/src/rust/tasks/presize_panels.rs +24 -1
  159. package/src/rust/tasks/restore_and_render.rs +0 -17
  160. package/src/rust/tasks/restore_panel.rs +129 -30
  161. package/src/rust/tasks/send_column_config.rs +4 -1
  162. package/src/rust/tasks/send_plugin_config.rs +1 -1
  163. package/src/rust/tasks/set_edit_mode.rs +1 -1
  164. package/src/rust/tasks/sync_update_panels.rs +147 -67
  165. package/src/rust/tasks/table_lifecycle.rs +7 -1
  166. package/src/rust/{components → ui}/containers/control_group.rs +25 -3
  167. package/src/rust/{components → ui}/containers/dropdown_menu.rs +5 -2
  168. package/src/rust/{components → ui}/containers/mod.rs +0 -4
  169. package/src/rust/{components → ui}/containers/scroll_panel.rs +0 -22
  170. package/src/rust/{components → ui}/containers/scroll_panel_item.rs +0 -13
  171. package/src/rust/{components → ui}/containers/select.rs +0 -6
  172. package/src/rust/{components → ui}/containers/sidebar.rs +5 -32
  173. package/src/rust/{components → ui}/containers/split_panel.rs +8 -80
  174. package/src/rust/{components → ui}/containers/tab_list.rs +15 -9
  175. package/src/rust/{components → ui}/context_menu.rs +8 -13
  176. package/src/rust/{presentation/drag_helpers.rs → ui/dragdrop.rs} +26 -31
  177. package/src/rust/{components → ui}/font_loader.rs +0 -26
  178. package/src/rust/{components → ui}/form/color_selector.rs +4 -2
  179. package/src/rust/{config/datetime_column_style/color_mode.rs → ui/form/intl_label.rs} +42 -42
  180. package/src/rust/{components → ui}/form/mirrored_textarea.rs +0 -53
  181. package/src/rust/{components → ui}/form/mod.rs +1 -10
  182. package/src/rust/{components → ui}/form/multi_stop_gradient_selector.rs +4 -5
  183. package/src/rust/{components → ui}/form/named_value_picker.rs +1 -6
  184. package/src/rust/{components → ui}/form/number_field.rs +1 -1
  185. package/src/rust/{components → ui}/form/number_range_field.rs +1 -1
  186. package/src/rust/{components → ui}/form/optional_field.rs +3 -1
  187. package/src/rust/{components → ui}/form/palette_selector.rs +4 -5
  188. package/src/rust/{components → ui}/form/select_enum_field.rs +2 -2
  189. package/src/rust/{components → ui}/form/select_value_field.rs +2 -2
  190. package/src/rust/ui/mod.rs +56 -0
  191. package/src/rust/ui/modal.rs +61 -0
  192. package/src/rust/{components → ui}/portal.rs +175 -79
  193. package/src/rust/{components/style/style_provider.rs → ui/style.rs} +4 -34
  194. package/src/rust/utils/completion.rs +0 -6
  195. package/src/rust/{config/css_scale.rs → utils/css.rs} +38 -35
  196. package/src/rust/utils/css_vars.rs +13 -0
  197. package/src/rust/utils/local_fonts.rs +395 -0
  198. package/src/rust/utils/mod.rs +4 -0
  199. package/src/rust/workspace.rs +47 -0
  200. package/src/svg/boolean-type.svg +3 -2
  201. package/src/svg/checkbox-checked-icon.svg +4 -7
  202. package/src/svg/checkbox-hover.svg +3 -3
  203. package/src/svg/checkbox-off.svg +2 -3
  204. package/src/svg/checkbox-on.svg +3 -3
  205. package/src/svg/checkbox-unchecked-icon.svg +3 -3
  206. package/src/svg/datagrid-select-column.svg +8 -15
  207. package/src/svg/datagrid-select-region.svg +8 -15
  208. package/src/svg/datagrid-select-row-tree.svg +7 -12
  209. package/src/svg/datagrid-select-row.svg +8 -13
  210. package/src/svg/date-type.svg +4 -23
  211. package/src/svg/drawer-tab-hover.svg +4 -6
  212. package/src/svg/drawer-tab-invert-hover.svg +5 -5
  213. package/src/svg/drawer-tab-invert.svg +3 -5
  214. package/src/svg/drawer-tab.svg +5 -5
  215. package/src/svg/mega-menu-icons-candlestick.svg +5 -37
  216. package/src/svg/mega-menu-icons-ohlc.svg +4 -39
  217. package/src/svg/mega-menu-icons-sunburst.svg +4 -38
  218. package/src/svg/mega-menu-icons-treemap.svg +3 -43
  219. package/src/svg/mega-menu-icons-y-scatter.svg +12 -72
  220. package/src/svg/new-panel-icon.svg +4 -0
  221. package/src/svg/number-type.svg +3 -3
  222. package/src/svg/radio-hover.svg +3 -3
  223. package/src/svg/radio-off.svg +3 -3
  224. package/src/svg/radio-on.svg +3 -3
  225. package/src/svg/status_ok.svg +3 -26
  226. package/src/svg/status_pending.svg +3 -0
  227. package/src/svg/string-type.svg +4 -8
  228. package/src/svg/theme-icon.svg +5 -5
  229. package/src/themes/blueprint.css +0 -57
  230. package/src/themes/botanical.css +0 -36
  231. package/src/themes/defaults.css +1 -24
  232. package/src/themes/dracula.css +0 -58
  233. package/src/themes/eggplant.css +0 -58
  234. package/src/themes/gruvbox-dark.css +0 -65
  235. package/src/themes/gruvbox.css +1 -39
  236. package/src/themes/icons.css +2 -8
  237. package/src/themes/intl/ar.css +198 -0
  238. package/src/themes/intl/de.css +63 -40
  239. package/src/themes/intl/es.css +58 -35
  240. package/src/themes/intl/fr.css +57 -34
  241. package/src/themes/intl/ja.css +59 -36
  242. package/src/themes/intl/pt.css +54 -31
  243. package/src/themes/intl/zh.css +65 -42
  244. package/src/themes/intl.css +34 -8
  245. package/src/themes/ledger.css +1 -59
  246. package/src/themes/monokai.css +0 -51
  247. package/src/themes/nord.css +0 -55
  248. package/src/themes/phosphor.css +0 -48
  249. package/src/themes/pro-dark.css +0 -37
  250. package/src/themes/pro.css +3 -23
  251. package/src/themes/solarized-dark.css +0 -31
  252. package/src/themes/solarized.css +1 -24
  253. package/src/themes/vaporwave.css +0 -44
  254. package/src/themes/velvet.css +0 -60
  255. package/src/ts/extensions.ts +0 -13
  256. package/src/ts/perspective-viewer.ts +2 -0
  257. package/src/ts/plugin.ts +9 -0
  258. package/src/ts/ts-rs/AddPanelOptions.ts +10 -0
  259. package/src/ts/ts-rs/{DatetimeColorMode.ts → GetViewMode.ts} +4 -1
  260. package/src/ts/ts-rs/GetViewOptions.ts +7 -0
  261. package/src/ts/ts-rs/RestoreOptions.ts +7 -1
  262. package/src/ts/ts-rs/RestoreWorkspaceOptions.ts +10 -0
  263. package/src/ts/ts-rs/ViewOnUpdateResp.ts +1 -1
  264. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +31 -20
  265. package/dist/esm/ts-rs/DatetimeColorMode.d.ts +0 -1
  266. package/dist/esm/ts-rs/FormatMode.d.ts +0 -1
  267. package/dist/esm/ts-rs/StringColorMode.d.ts +0 -1
  268. package/src/css/plugin-settings-panel.css +0 -171
  269. package/src/rust/components/modal.rs +0 -177
  270. package/src/rust/components/string_column_style.rs +0 -121
  271. package/src/rust/config/string_column_style.rs +0 -135
  272. package/src/rust/custom_elements/copy_dropdown.rs +0 -219
  273. package/src/rust/custom_elements/export_dropdown.rs +0 -216
  274. package/src/rust/custom_elements/modal.rs +0 -299
  275. package/src/ts/ts-rs/FormatMode.ts +0 -3
  276. package/src/ts/ts-rs/StringColorMode.ts +0 -3
  277. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline0.js +0 -0
  278. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline1.js +0 -0
  279. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline2.js +0 -0
  280. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline3.js +0 -0
  281. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline4.js +0 -0
  282. /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline5.js +0 -0
  283. /package/src/css/{containers → ui/containers}/scroll-panel.css +0 -0
  284. /package/src/css/{containers → ui/containers}/split-panel.css +0 -0
  285. /package/src/css/{dom → ui/dom}/checkbox.css +0 -0
  286. /package/src/css/{dom → ui/dom}/scrollbar.css +0 -0
  287. /package/src/css/{dom → ui/dom}/select.css +0 -0
  288. /package/src/css/{form → ui/form}/mirrored-textarea.css +0 -0
  289. /package/src/rust/components/{form → code_editor}/highlight.rs +0 -0
  290. /package/src/rust/{components → ui}/containers/sidebar_close_button.rs +0 -0
  291. /package/src/rust/{components → ui}/form/number_input.rs +0 -0
@@ -112,6 +112,11 @@ pub struct RendererData {
112
112
  /// plugin's bucket.
113
113
  pub plugin_config_changed: PubSub<serde_json::Map<String, serde_json::Value>>,
114
114
 
115
+ /// Fires after the active plugin's per-column bucket changes by any path
116
+ /// (edit, restore or reset), unlike `column_style_changed` which covers
117
+ /// edits only.
118
+ pub columns_config_changed: PubSub<ColumnConfigMap>,
119
+
115
120
  /// `true` while the active plugin's "rendering N of M" warning is
116
121
  /// dismissable.
117
122
  pub render_warning: Cell<bool>,
@@ -120,6 +125,10 @@ pub struct RendererData {
120
125
  /// [`Renderer::presize_with_box`] presize calls.
121
126
  presize_pending: Cell<u32>,
122
127
 
128
+ /// The `(width, height)` the plugin last painted at through a presize,
129
+ /// consumed by the post-commit reactive resize.
130
+ presized_box: Cell<Option<(f64, f64)>>,
131
+
123
132
  /// Debounce slot for geometry tasks (`resize` / presize), separate from
124
133
  /// the default slot data-update redraws coalesce on. Invariant: a
125
134
  /// geometry request must never resolve via a parked DATA task — a
@@ -160,14 +169,7 @@ pub struct RendererData {
160
169
 
161
170
  /// The effective theme stamped at the active plugin's last `--psp-*`
162
171
  /// CSS CAPTURE — its first paint ([`Renderer::draw_view`]) or last
163
- /// [`Renderer::restyle_all`]. `None` = no capture has happened. The
164
- /// state behind [`Renderer::needs_restyle`]: restyle necessity is a
165
- /// comparison against what the plugin actually captured, never
166
- /// inferred from which call site mutated a theme record (the
167
- /// raycasting boot double render — see
168
- /// `PLUGIN_DRAW_INVARIANT_PLAN.md`, captured-theme revision). Same
169
- /// lifecycle as [`Self::has_drawn`]: cleared on plugin swap,
170
- /// `dispose` and `delete`; written only inside locked dispatches.
172
+ /// [`Renderer::restyle_all`].
171
173
  captured_theme: RefCell<Option<Option<String>>>,
172
174
 
173
175
  /// The [`RenderContext`] of the currently-bound `View` (built at bind
@@ -266,8 +268,10 @@ impl Renderer {
266
268
  selection_changed: Default::default(),
267
269
  column_style_changed: Default::default(),
268
270
  plugin_config_changed: Default::default(),
271
+ columns_config_changed: Default::default(),
269
272
  render_warning: Cell::new(true),
270
273
  presize_pending: Cell::new(0),
274
+ presized_box: Cell::new(None),
271
275
  on_render_limits_changed: Default::default(),
272
276
  slot_name: Default::default(),
273
277
  theme: Default::default(),
@@ -315,14 +319,7 @@ impl Renderer {
315
319
 
316
320
  /// Whether the active plugin's captured `--psp-*` CSS is STALE — the
317
321
  /// effective theme differs from the one stamped at the plugin's last
318
- /// CSS capture (first paint / last restyle). The state-keyed gate for
319
- /// every theme-driven `restyle_all` (the `has_drawn` analog for
320
- /// `restyle` — `PLUGIN_DRAW_INVARIANT_PLAN.md`, captured-theme
321
- /// revision): a caller that just mutated a theme RECORD may not need a
322
- /// restyle at all if the plugin's capture already reflects the new
323
- /// value (e.g. the same restore also performed the first paint,
324
- /// post-stamp). `false` when no capture exists yet — the owed first
325
- /// paint captures fresh by construction ("stamp before draw").
322
+ /// CSS capture (first paint / last restyle).
326
323
  pub fn needs_restyle(&self) -> bool {
327
324
  match &*self.0.captured_theme.borrow() {
328
325
  Some(captured) => *captured != self.theme(),
@@ -336,17 +333,6 @@ impl Renderer {
336
333
  /// [`Self::delete`], which clears the entire light DOM). Removes the
337
334
  /// plugin (`slot=<id>`) and any panel-scoped aux element it mounted
338
335
  /// (e.g. the datagrid toolbar, `slot=statusbar-extra-<id>`).
339
- ///
340
- /// The teardown is DEFERRED through this renderer's draw lock: spawned
341
- /// draws are uncancellable, so a synchronous `plugin.delete()` here could
342
- /// land mid-`plugin.draw()`, which the serialized-call contract forbids
343
- /// (see [`crate::js::plugin`]). Deferral is invisible — the caller
344
- /// (`eject_panel`) has already removed the panel from the `Workspace`, so
345
- /// the same commit unmounts its frame and the plugin element sits
346
- /// unslotted (unrendered) until teardown lands; panel ids are never
347
- /// reused, so it can't collide with a replacement panel's slot. Draws
348
- /// still queued behind the lock no-op via the synchronous session reset
349
- /// (`get_view()` → `None`).
350
336
  pub fn dispose(&self) -> ApiFuture<()> {
351
337
  self.0.has_drawn.set(false);
352
338
  self.0.captured_theme.borrow_mut().take();
@@ -488,6 +474,12 @@ impl Renderer {
488
474
  Ok(self.0.has_drawn.get())
489
475
  }
490
476
 
477
+ /// Take the box the plugin last painted at through a presize (see
478
+ /// `RendererData::presized_box`).
479
+ pub fn take_presized_box(&self) -> Option<(f64, f64)> {
480
+ self.0.presized_box.take()
481
+ }
482
+
491
483
  /// Mount the selected plugin element into the viewer's light DOM without
492
484
  /// drawing it (see [`activate::mount_plugin`] — idempotent). Pure query:
493
485
  /// a renderer with no selection is a no-op, deferring to the draw path's
@@ -695,6 +687,7 @@ impl Renderer {
695
687
  /// suitable for passing as a Yew prop. Called by the root component
696
688
  /// whenever a renderer-related PubSub event fires.
697
689
  pub fn to_props(&self, render_limits: Option<RenderLimits>) -> RendererProps {
690
+ let render_limits = render_limits.filter(RenderLimits::is_capped);
698
691
  let has_plugin = self.active_plugin().is_some();
699
692
  if has_plugin {
700
693
  let config = self.metadata();
@@ -708,6 +701,7 @@ impl Renderer {
708
701
  .into();
709
702
 
710
703
  let plugin_config = PtrEqRc::new(self.get_plugin_config());
704
+ let columns_config = PtrEqRc::new(self.all_columns_configs());
711
705
  RendererProps {
712
706
  plugin_name,
713
707
  config,
@@ -715,6 +709,7 @@ impl Renderer {
715
709
  available_plugins,
716
710
  is_chart,
717
711
  plugin_config,
712
+ columns_config,
718
713
  }
719
714
  } else {
720
715
  RendererProps {
@@ -724,6 +719,7 @@ impl Renderer {
724
719
  available_plugins: PtrEqRc::new(vec![]),
725
720
  is_chart: false,
726
721
  plugin_config: PtrEqRc::default(),
722
+ columns_config: PtrEqRc::default(),
727
723
  }
728
724
  }
729
725
  }
@@ -19,14 +19,18 @@ use crate::session::column_defaults_update::ViewConfigUpdateExt;
19
19
  use crate::session::drag_drop_update::ViewConfigExt as DragDropExt;
20
20
  use crate::session::metadata::SessionMetadataRc;
21
21
  use crate::session::replace_expression_update::ViewConfigExt as ReplaceExprExt;
22
- use crate::session::{ColumnStats, TableErrorState, ViewStats};
22
+ use crate::session::{ColumnStats, TableErrorState};
23
23
  use crate::utils::*;
24
24
 
25
+ /// The panel's table binding as the status indicator and chrome see it:
26
+ /// bound, a `load()` in flight, or a named table awaiting its host (see
27
+ /// `Session::pending_table`).
25
28
  #[derive(Clone, Debug, PartialEq, Default)]
26
29
  pub enum TableLoadState {
27
30
  #[default]
28
31
  Loaded,
29
32
  Loading,
33
+ Pending,
30
34
  }
31
35
 
32
36
  /// Value-semantic snapshot of the session state read by the root component.
@@ -39,8 +43,9 @@ pub struct SessionProps {
39
43
  /// The current `ViewConfig` driving the active `View`.
40
44
  pub config: PtrEqRc<ViewConfig>,
41
45
 
42
- /// Row/column statistics for the status bar.
43
- pub stats: Option<ViewStats>,
46
+ /// Whether the view stats carry table dimensions yet, the status
47
+ /// indicator's loaded/uninitialized split.
48
+ pub has_table_cells: bool,
44
49
 
45
50
  /// `true` if a `Table` has been loaded into this session.
46
51
  pub has_table: Option<TableLoadState>,
@@ -10,10 +10,11 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- use std::cell::Cell;
13
+ use std::cell::{Cell, RefCell};
14
14
  use std::rc::Rc;
15
15
 
16
16
  use perspective_client::config::*;
17
+ use perspective_client::proto::ViewDimensionsResp;
17
18
  use perspective_client::{OnUpdateOptions, View};
18
19
  use wasm_bindgen::prelude::*;
19
20
  use yew::prelude::*;
@@ -41,6 +42,10 @@ struct ViewSubscriptionData {
41
42
  on_stats: Callback<ViewStats>,
42
43
  on_update: Option<Callback<()>>,
43
44
  is_deleted: Rc<Cell<bool>>,
45
+
46
+ /// The bound `View`'s latest known dimensions, written before
47
+ /// `on_update`/`on_stats` fire.
48
+ dimensions: Rc<RefCell<Option<ViewDimensionsResp>>>,
44
49
  }
45
50
 
46
51
  /// A subscription to `on_update()` events from a Perspective `View()`, managing
@@ -52,20 +57,21 @@ pub struct ViewSubscription {
52
57
  impl ViewSubscriptionData {
53
58
  /// Main handler when underlying `View()` calls `on_update()`.
54
59
  async fn on_view_update(self) -> ApiResult<JsValue> {
60
+ self.clone().update_view_stats().await?;
55
61
  if let Some(on_update) = &self.on_update {
56
62
  on_update.emit(());
57
63
  };
58
64
 
59
- self.clone().update_view_stats().await?;
60
65
  Ok(JsValue::UNDEFINED)
61
66
  }
62
67
 
63
68
  async fn update_view_stats(self) -> ApiResult<JsValue> {
64
69
  let dimensions = self.view.dimensions().await?;
65
- let num_rows = dimensions.num_table_rows as u32;
66
- let num_cols = dimensions.num_table_columns as u32;
67
- let virtual_rows = dimensions.num_view_rows as u32;
68
- let virtual_cols = dimensions.num_view_columns as u32;
70
+ let num_rows = dimensions.num_table_rows;
71
+ let num_cols = dimensions.num_table_columns;
72
+ let virtual_rows = dimensions.num_view_rows;
73
+ let virtual_cols = dimensions.num_view_columns;
74
+ *self.dimensions.borrow_mut() = Some(dimensions);
69
75
  let stats = ViewStats {
70
76
  num_table_cells: Some((num_rows, num_cols)),
71
77
  num_view_cells: Some((virtual_rows, virtual_cols)),
@@ -119,6 +125,7 @@ impl ViewSubscription {
119
125
  callback_id: Rc::default(),
120
126
  on_update,
121
127
  is_deleted: Rc::default(),
128
+ dimensions: Rc::default(),
122
129
  };
123
130
 
124
131
  if data.on_update.is_some() {
@@ -160,6 +167,12 @@ impl ViewSubscription {
160
167
  &self.data.view
161
168
  }
162
169
 
170
+ /// The bound `View`'s latest known dimensions (`None` until the first
171
+ /// fetch resolves).
172
+ pub fn dimensions(&self) -> Option<ViewDimensionsResp> {
173
+ self.data.dimensions.borrow().clone()
174
+ }
175
+
163
176
  /// User-facing snapshot of the [`ViewConfig`] the bound `View` was
164
177
  /// constructed from (the persisted config at build time — global-filter
165
178
  /// overlay excluded). This is the [`ViewConfig`] consistent with the