@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
@@ -12,24 +12,30 @@
12
12
  */
13
13
 
14
14
  /* Panel context menu (right-click a panel). The `<perspective-context-menu>`
15
- * host is body-mounted by `PortalModal` (which owns position/z-index inline)
16
- * and themed by the document theme rules' modal selector groups — chrome like
17
- * `background-color`/`color`/`border` lands on the HOST from `defaults.css` /
18
- * each theme's `perspective-context-menu[theme="X"]` group, exactly like the
19
- * Copy/Export menus. Only the interior layout + item states live here. */
15
+ * host is a viewer light-DOM child in the top layer (see `PortalModal`),
16
+ * themed by the `--psp-*` vars it inherits; its chrome lives here, exactly
17
+ * like the Copy/Export menus' surface. */
18
+
19
+ @import "./dropdown-menu-items.css";
20
20
 
21
21
  :host {
22
+ overflow: visible;
23
+ padding: 0;
24
+ background-color: var(--psp--background-color, #ffffff);
25
+ color: var(--psp--color, #161616);
26
+ border: 1px solid var(--psp-inactive--color, #ababab);
27
+ border-radius: 0 0 2px 2px;
22
28
  outline: none;
23
29
  user-select: none;
24
30
  font-size: 12px;
25
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
31
+ box-shadow: var(--psp-dropdown--box-shadow);
26
32
  }
27
33
 
28
34
  .context-menu {
29
35
  display: flex;
30
36
  flex-direction: column;
31
37
  min-width: 120px;
32
- padding: 4px 0;
38
+ padding: 0px 0;
33
39
  }
34
40
 
35
41
  .context-menu-item {
@@ -73,17 +79,11 @@
73
79
  }
74
80
  }
75
81
 
76
- /* Hover flyout. Positioned OUTSIDE the host's box, so the host-level theme
77
- * chrome (see the :host comment above) doesn't paint it — rebuild the same
78
- * chrome from the modal selector groups' vars. Edge-adjacent (`left: 100%`,
79
- * no gap) so the pointer never leaves the hover chain crossing into it;
80
- * `top: -5px` aligns its first row with the parent row (4px menu padding +
81
- * 1px border). */
82
82
  .context-menu-submenu {
83
83
  display: none;
84
84
  position: absolute;
85
85
  left: 100%;
86
- top: -5px;
86
+ top: -1px;
87
87
  max-height: 50vh;
88
88
  overflow-y: auto;
89
89
  background-color: var(--psp--background-color, white);
@@ -93,10 +93,16 @@
93
93
  * foreground. */
94
94
  color: var(--psp--color);
95
95
  border: 1px solid var(--psp-inactive--color);
96
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
96
+ box-shadow: var(--psp-dropdown--box-shadow);
97
+ }
98
+
99
+ .context-menu-submenu > .new-panel-menu {
100
+ display: flex;
101
+ flex-direction: column;
102
+ padding: 8px;
103
+ min-width: 120px;
97
104
  }
98
105
 
99
- /* Non-interactive group label (e.g. client names in the "New" sub-menu). */
100
106
  .context-menu-header {
101
107
  padding: 4px 12px 2px;
102
108
  cursor: default;
@@ -0,0 +1,66 @@
1
+ /* ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ * ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ * ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ * ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ * ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ * ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ * ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ * ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ * ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ * ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+ */
13
+
14
+ .dropdown-group-label {
15
+ font-size: 0.75em;
16
+ color: var(--psp-inactive--color);
17
+ &:not(:first-of-type) {
18
+ margin-top: 16px;
19
+ }
20
+ }
21
+
22
+ .dropdown-group-label[data-label="new-from-table"]::before {
23
+ content: var(--psp-label--new-from-table--content, var(--psp-missing));
24
+ }
25
+
26
+ .dropdown-group-label[data-label="new-from-panel"]::before {
27
+ content: var(--psp-label--new-from-panel--content, var(--psp-missing));
28
+ }
29
+
30
+ .dropdown-group-sublabel {
31
+ font-size: 0.75em;
32
+ text-transform: uppercase;
33
+ color: var(--psp-inactive--color);
34
+ margin-top: 6px;
35
+ }
36
+
37
+ .dropdown-group-container {
38
+ display: flex;
39
+ flex-direction: column;
40
+ margin: 0;
41
+ }
42
+
43
+ .dropdown-group-label,
44
+ .dropdown-group-sublabel,
45
+ .dropdown-group-container > span,
46
+ .no-results {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ margin: 0 -8px;
50
+ padding: 0 8px;
51
+ }
52
+
53
+ .dropdown-menu-item {
54
+ cursor: pointer;
55
+ min-height: 22px;
56
+ &:hover {
57
+ background-color: var(--psp--color);
58
+ color: var(--psp--background-color);
59
+ }
60
+ }
61
+
62
+ .no-results {
63
+ font-style: italic;
64
+ padding: 6px 24px;
65
+ color: #ccc;
66
+ }
@@ -11,15 +11,17 @@
11
11
  * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
  */
13
13
 
14
+ @import "./dropdown-menu-items.css";
15
+
14
16
  :host {
15
- position: fixed;
16
- z-index: 10000;
17
+ overflow: visible;
18
+ background-color: var(--psp--background-color, #ffffff);
19
+ color: var(--psp--color, #161616);
20
+ border: 1px solid var(--psp-inactive--color, #ababab);
21
+ border-radius: 0 0 2px 2px;
17
22
  outline: none;
18
- font-size: 0.75em;
19
- border: inherit;
20
- box-shadow: 0 2px 4px 0 rgb(0 0 0 / 10%);
23
+ box-shadow: var(--psp-dropdown--box-shadow);
21
24
  user-select: none;
22
- background-color: white;
23
25
  padding: 8px;
24
26
 
25
27
  display: flex;
@@ -45,51 +47,4 @@
45
47
  color: var(--psp-error--color, #ff0000);
46
48
  border-color: var(--psp-error--color, #ff0000);
47
49
  }
48
-
49
- .selected {
50
- background-color: rgba(0, 0, 0, 0.05);
51
- }
52
-
53
- .dropdown-group-label {
54
- color: var(--psp-inactive--color);
55
-
56
- &:not(:first-of-type) {
57
- margin-top: 16px;
58
- }
59
- }
60
-
61
- .dropdown-group-container {
62
- display: flex;
63
- flex-direction: column;
64
- margin: 0;
65
- }
66
-
67
- span {
68
- min-height: 22px;
69
- display: inline-flex;
70
- align-items: center;
71
- margin: 0 -8px;
72
- padding: 0 8px;
73
- }
74
-
75
- .dropdown-group-container span {
76
- cursor: pointer;
77
- }
78
-
79
- .no-results {
80
- font-style: italics;
81
- padding: 6px 24px;
82
- color: #ccc;
83
- }
84
- }
85
-
86
- :host(:hover) {
87
- .selected {
88
- background-color: transparent;
89
- }
90
-
91
- .dropdown-group-container span:hover {
92
- background-color: var(--psp--color);
93
- color: var(--psp--background-color);
94
- }
95
50
  }
@@ -13,7 +13,8 @@
13
13
 
14
14
  :host {
15
15
  #format-tab {
16
- overflow: auto;
16
+ overflow-y: auto;
17
+ overflow-x: hidden;
17
18
  scrollbar-gutter: stable;
18
19
  }
19
20
 
@@ -14,6 +14,7 @@
14
14
  :host {
15
15
  --settings-panel-z-index: 10;
16
16
  --psp--color: #ff0000;
17
+ --psp-missing: "__MISSING__";
17
18
  }
18
19
 
19
20
  :host(.shift-active) .shift-alt-icon {
@@ -89,7 +90,9 @@
89
90
  pointer-events: var(--override-content-pointer-events);
90
91
  }
91
92
 
92
- ::slotted(:not([slot^="statusbar-extra"]):not([slot^="tab-"])) {
93
+ ::slotted(
94
+ :not([slot^="statusbar-extra"]):not([slot^="tab-"]):not([slot="modal"])
95
+ ) {
93
96
  position: absolute;
94
97
  inset: 0;
95
98
  background-color: var(--psp--background-color) !important;
@@ -100,7 +103,10 @@
100
103
  -1.75px 2.75px 0 2.75px var(--psp-inactive--color);
101
104
  }
102
105
 
103
- .overlay ::slotted(:not([slot^="statusbar-extra"]):not([slot^="tab-"])) {
106
+ .overlay
107
+ ::slotted(
108
+ :not([slot^="statusbar-extra"]):not([slot^="tab-"]):not([slot="modal"])
109
+ ) {
104
110
  box-shadow:
105
111
  2.25px 2.25px 0 2.25px var(--psp--background-color),
106
112
  -2.25px 2.25px 0 2.25px var(--psp--background-color),
@@ -338,7 +344,6 @@
338
344
  z-index: 0;
339
345
  position: relative;
340
346
  height: 100%;
341
- box-shadow: var(--plugin--box-shadow, none);
342
347
  overflow: hidden;
343
348
  border: var(--psp-plugin--border, none);
344
349
  background: var(
@@ -487,8 +492,9 @@
487
492
  }
488
493
 
489
494
  & > .split-panel-divider {
495
+ background-color: #00000020;
490
496
  border-top: 1px solid var(--psp-inactive--color, #6e6e6e);
491
- border-bottom: 2px solid var(--psp-inactive--color, #6e6e6e);
497
+ border-bottom: 1px solid var(--psp-inactive--color, #6e6e6e);
492
498
  margin-left: -9px;
493
499
  margin-right: 0px;
494
500
  flex: 0 0 4px;
@@ -584,9 +590,11 @@
584
590
  }
585
591
 
586
592
  .settings_tab {
593
+ overflow: hidden;
594
+ text-overflow: ellipsis;
587
595
  border-right: 1px solid var(--psp-inactive--color);
588
596
  cursor: pointer;
589
- padding: 6px 8px;
597
+ padding: 5px 8px 7px 8px;
590
598
  font-size: var(--label--font-size, 0.75em);
591
599
  text-transform: uppercase;
592
600
  flex: 0 1 100px;
@@ -605,7 +613,7 @@
605
613
  background-color: transparent;
606
614
  border-bottom: 1px solid transparent;
607
615
  box-shadow: 0px 9px 0px -8px var(--psp-inactive--color);
608
- height: calc(100% - 1px);
616
+ height: 23px;
609
617
  }
610
618
  }
611
619
 
@@ -639,36 +647,28 @@
639
647
  }
640
648
 
641
649
  .sidebar_border {
642
- height: 2px;
650
+ height: 3px;
651
+ border-bottom: 1px solid var(--psp-inactive--color, #6e6e6e);
643
652
  width: 100%;
644
- background-color: var(--psp-inactive--color, #6e6e6e);
645
- margin-top: 1px;
653
+ background-color: rgba(0, 0, 0, 0.15);
646
654
  flex-shrink: 0;
647
655
  flex-grow: 0;
648
656
  }
649
657
 
650
658
  #query_tabbar_tab:before {
651
- content: var(--psp-label--query-tab--content);
659
+ content: var(--psp-label--query-tab--content, var(--psp-missing));
652
660
  }
653
661
 
654
662
  #plugin_tabbar_tab:before {
655
- content: var(--psp-label--plugin-tab--content);
663
+ content: var(--psp-label--plugin-tab--content, var(--psp-missing));
656
664
  }
657
665
 
658
666
  #debug_tabbar_tab:before {
659
- content: var(--psp-label--debug-tab--content);
667
+ content: var(--psp-label--debug-tab--content, var(--psp-missing));
660
668
  }
661
669
 
662
670
  #chat_tabbar_tab:before {
663
- content: var(--psp-label--chat-tab--content);
664
- }
665
-
666
- label#stack-label:before {
667
- content: var(--psp-label--stack--content, "Stack");
668
- }
669
-
670
- label#alt_axis-label:before {
671
- content: var(--psp-label--alt-axis--content, "Alt Axis");
671
+ content: var(--psp-label--chat-tab--content, var(--psp-missing));
672
672
  }
673
673
  }
674
674
 
@@ -853,7 +853,10 @@
853
853
  user-select: none;
854
854
  &:before {
855
855
  text-transform: uppercase;
856
- content: var(--psp-label--chat-reasoning--content);
856
+ content: var(
857
+ --psp-label--chat-reasoning--content,
858
+ var(--psp-missing)
859
+ );
857
860
  font-size: var(--psp-label--font-size, 0.75em);
858
861
  }
859
862
  }
@@ -898,7 +901,7 @@
898
901
  align-items: flex-end;
899
902
 
900
903
  /* The prompt is a `MirroredTextarea` (see
901
- * `form/mirrored-textarea.css`): it is exactly as tall as its
904
+ * `ui/form/mirrored-textarea.css`): it is exactly as tall as its
902
905
  * text, so this wrapper owns the visible box and caps how far
903
906
  * that growth goes before it scrolls instead. */
904
907
  #chat_input_scroll {
@@ -933,7 +936,10 @@
933
936
  * `placeholder` attribute is untranslatable and is
934
937
  * kept only for assistive tech. */
935
938
  &.is-empty:before {
936
- content: var(--psp-label--chat-placeholder--content);
939
+ content: var(
940
+ --psp-label--chat-placeholder--content,
941
+ var(--psp-missing)
942
+ );
937
943
  color: var(--psp-inactive--color, #6e6e6e);
938
944
  }
939
945
  }
@@ -965,11 +971,11 @@
965
971
  }
966
972
 
967
973
  #chat_send_button:before {
968
- content: var(--psp-label--chat-send--content);
974
+ content: var(--psp-label--chat-send--content, var(--psp-missing));
969
975
  }
970
976
 
971
977
  #chat_stop_button:before {
972
- content: var(--psp-label--chat-stop--content);
978
+ content: var(--psp-label--chat-stop--content, var(--psp-missing));
973
979
  }
974
980
  }
975
981
 
@@ -22,7 +22,7 @@ use wasm_bindgen::prelude::*;
22
22
 
23
23
  use super::client::protocol::{FunctionDef, ToolDef};
24
24
  use super::docs::{DocsBundle, DocsCell};
25
- use crate::config::{ColumnConfigSchema, ControlSpec};
25
+ use crate::config::{Alignment, ColumnConfigSchema, ControlSpec};
26
26
  use crate::custom_elements::viewer::PerspectiveViewerElement;
27
27
  use crate::queries::{
28
28
  get_column_config_schema, get_plugin_config_schema, get_viewer_config, validate_expr,
@@ -628,6 +628,78 @@ fn control_schema_entries(spec: &ControlSpec) -> Vec<(String, Value)> {
628
628
  ControlSpec::String { key, default, .. } => {
629
629
  vec![(key.clone(), json!({ "type": "string", "default": default }))]
630
630
  },
631
+ ControlSpec::Font {
632
+ key,
633
+ default,
634
+ size,
635
+ bold,
636
+ italic,
637
+ } => {
638
+ let mut out = vec![(
639
+ key.clone(),
640
+ json!({
641
+ "type": "string",
642
+ "description": "A CSS font family: a generic keyword (`inherit`, `monospace`, `sans-serif`, `serif`, `system-ui`) or an installed font name",
643
+ "default": default,
644
+ }),
645
+ )];
646
+
647
+ if let Some(size) = size {
648
+ let mut node = json!({
649
+ "type": "number",
650
+ "description": "Font size in CSS pixels",
651
+ "default": size.default,
652
+ });
653
+
654
+ if let Some(min) = size.min {
655
+ node["minimum"] = json!(min);
656
+ }
657
+
658
+ if let Some(max) = size.max {
659
+ node["maximum"] = json!(max);
660
+ }
661
+
662
+ out.push((size.key.clone(), node));
663
+ }
664
+
665
+ for (toggle, description) in [(bold, "Bold text"), (italic, "Italic text")] {
666
+ if let Some(toggle) = toggle {
667
+ out.push((
668
+ toggle.key.clone(),
669
+ json!({ "type": "boolean", "description": description, "default": toggle.default }),
670
+ ));
671
+ }
672
+ }
673
+
674
+ out
675
+ },
676
+ ControlSpec::Alignment {
677
+ key,
678
+ default,
679
+ corners,
680
+ } => {
681
+ let cells: &[Alignment] = if *corners {
682
+ &Alignment::CORNERS
683
+ } else {
684
+ &Alignment::ALL
685
+ };
686
+
687
+ let mut node = json!({
688
+ "type": "string",
689
+ "enum": cells.iter().map(|x| x.as_str()).collect::<Vec<_>>(),
690
+ "description": if *corners {
691
+ "Anchor corner of a 3×3 grid: `top-left`, `top-right`, `bottom-left` or `bottom-right`"
692
+ } else {
693
+ "Anchor cell of a 3×3 grid: a corner `top-left|top-right|bottom-left|bottom-right`, an edge `top|left|right|bottom`, or `center`"
694
+ },
695
+ });
696
+
697
+ if let Some(default) = default {
698
+ node["default"] = json!(default.as_str());
699
+ }
700
+
701
+ vec![(key.clone(), node)]
702
+ },
631
703
  ControlSpec::Color { key, default } => vec![(
632
704
  key.clone(),
633
705
  json!({
@@ -683,10 +755,6 @@ fn control_schema_entries(spec: &ControlSpec) -> Vec<(String, Value)> {
683
755
  "date_format".to_owned(),
684
756
  json!({ "description": "Datetime display format: a style preset or custom format fields" }),
685
757
  )],
686
- ControlSpec::StringFormat => vec![(
687
- "format".to_owned(),
688
- json!({ "description": "String display format" }),
689
- )],
690
758
  ControlSpec::NumberSeriesStyle { .. } => vec![
691
759
  (
692
760
  "chart_type".to_owned(),
@@ -977,7 +1045,7 @@ impl PerspectiveViewerElement {
977
1045
 
978
1046
  let before = self.agent_panel_names();
979
1047
  let js_config = js_sys::JSON::parse(&args.config.to_string())?;
980
- let added = self.addPanel(js_config.unchecked_into());
1048
+ let added = self.addPanel(js_config.unchecked_into(), None);
981
1049
  let result = wasm_bindgen_futures::JsFuture::from(js_sys::Promise::from(added)).await;
982
1050
  let id = match result {
983
1051
  Ok(id) => id
@@ -1048,7 +1116,12 @@ impl PerspectiveViewerElement {
1048
1116
  let columns_config = serde_json::to_value(&viewer_config.columns_config)?;
1049
1117
  let plugin_schema = {
1050
1118
  let view_config = panel.session.get_view_config();
1051
- get_plugin_config_schema(&panel.renderer, &view_config).ok()
1119
+ get_plugin_config_schema(
1120
+ &panel.renderer,
1121
+ &view_config,
1122
+ Some(&viewer_config.panel.plugin_config),
1123
+ )
1124
+ .ok()
1052
1125
  };
1053
1126
 
1054
1127
  let column_schema = match &args.column {
@@ -18,7 +18,7 @@
18
18
  use yew::prelude::*;
19
19
 
20
20
  use crate::agent::{AgentSlot, ChatEntry, render_markdown};
21
- use crate::components::form::mirrored_textarea::MirroredTextarea;
21
+ use crate::ui::MirroredTextarea;
22
22
 
23
23
  #[derive(Properties, PartialEq)]
24
24
  struct ChatReasoningProps {
@@ -10,6 +10,8 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
+ mod highlight;
14
+
13
15
  use std::rc::Rc;
14
16
 
15
17
  use perspective_client::ExprValidationError;
@@ -17,10 +19,10 @@ use wasm_bindgen::JsCast;
17
19
  use web_sys::*;
18
20
  use yew::prelude::*;
19
21
 
20
- use crate::components::form::highlight::highlight;
21
- use crate::components::form::mirrored_textarea::MirroredTextarea;
22
+ use self::highlight::highlight;
22
23
  use crate::components::function_dropdown::{FunctionDropDownElement, FunctionDropDownPortal};
23
24
  use crate::exprtk::{Cursor, tokenize};
25
+ use crate::ui::MirroredTextarea;
24
26
  use crate::utils::*;
25
27
 
26
28
  #[derive(Properties, PartialEq)]
@@ -21,9 +21,9 @@ use yew::html::ImplicitClone;
21
21
  use yew::prelude::*;
22
22
 
23
23
  use super::column_selector::InPlaceColumn;
24
- use super::portal::PortalModal;
25
24
  use super::style::StyleSurface;
26
25
  use crate::session::Session;
26
+ use crate::ui::PortalModal;
27
27
  use crate::utils::*;
28
28
  use crate::*;
29
29
 
@@ -216,7 +216,7 @@ impl Component for ColumnDropDownPortal {
216
216
  html! {
217
217
  <PortalModal
218
218
  tag_name="perspective-dropdown"
219
- surface={StyleSurface::ColumnDropdown}
219
+ sheet={StyleSurface::ColumnDropdown.sheet()}
220
220
  {target}
221
221
  own_focus=false
222
222
  {on_close}
@@ -70,6 +70,13 @@ pub struct ActiveColumnProps {
70
70
  #[prop_or_default]
71
71
  pub is_window: bool,
72
72
 
73
+ /// Whether this column's `columns_config` entry holds overridden keys.
74
+ #[prop_or_default]
75
+ pub is_modified: bool,
76
+
77
+ #[prop_or_default]
78
+ pub is_last_column: bool,
79
+
73
80
  /// Whether the expression/config edit button should be shown. Computed
74
81
  /// by the parent (`is_expression || can_render_column_styles`).
75
82
  #[prop_or_default]
@@ -100,6 +107,7 @@ impl PartialEq for ActiveColumnProps {
100
107
  && self.is_editing == rhs.is_editing
101
108
  && self.is_expression == rhs.is_expression
102
109
  && self.is_window == rhs.is_window
110
+ && self.is_modified == rhs.is_modified
103
111
  && self.show_edit_btn == rhs.show_edit_btn
104
112
  && self.col_type == rhs.col_type
105
113
  && self.metadata == rhs.metadata
@@ -216,6 +224,10 @@ impl Component for ActiveColumn {
216
224
  outer_classes.push("dragdrop-hover");
217
225
  }
218
226
 
227
+ if ctx.props().is_modified {
228
+ outer_classes.push("is-modified");
229
+ }
230
+
219
231
  let name = match &ctx.props().name {
220
232
  ActiveColumnState {
221
233
  label,
@@ -287,7 +299,7 @@ impl Component for ActiveColumn {
287
299
  <div
288
300
  class={outer_classes}
289
301
  data-label={label}
290
- style={format!("--default-column-title:var(--column-selector-column-{path}--content)")}
302
+ style={format!("--default-column-title:var(--psp-label--column-{path}--content)")}
291
303
  data-index={ctx.props().idx.to_string()}
292
304
  ondragenter={ondragenter.clone()}
293
305
  >
@@ -301,7 +313,7 @@ impl Component for ActiveColumn {
301
313
  <div
302
314
  class={outer_classes}
303
315
  data-label={label}
304
- style={format!("--default-column-title:var(--column-selector-column-{path}--content)")}
316
+ style={format!("--default-column-title:var(--psp-label--column-{path}--content)")}
305
317
  data-index={ctx.props().idx.to_string()}
306
318
  ondragenter={ondragenter.clone()}
307
319
  >
@@ -310,7 +322,9 @@ impl Component for ActiveColumn {
310
322
  }
311
323
  },
312
324
  ((label, ColumnState::Named(name)), Some(col_type)) => {
313
- let is_required = ctx.props().get_is_required(ctx.props().idx);
325
+ let is_required =
326
+ ctx.props().is_last_column || ctx.props().get_is_required(ctx.props().idx);
327
+
314
328
  let remove_column = if is_required {
315
329
  None
316
330
  } else {
@@ -330,11 +344,12 @@ impl Component for ActiveColumn {
330
344
  let event_name = name.to_owned();
331
345
  let presentation = ctx.props().presentation.clone();
332
346
  move |event: DragEvent| {
333
- presentation.set_drag_image(&event).unwrap();
334
- presentation.notify_drag_start(
335
- event_name.to_string(),
336
- DragEffect::Move(DragTarget::Active),
337
- );
347
+ if presentation.set_drag_image(&event) {
348
+ presentation.notify_drag_start(
349
+ event_name.to_string(),
350
+ DragEffect::Move(DragTarget::Active),
351
+ );
352
+ }
338
353
 
339
354
  MouseLeave(false)
340
355
  }
@@ -359,7 +374,7 @@ impl Component for ActiveColumn {
359
374
  <div
360
375
  class={outer_classes}
361
376
  data-label={label}
362
- style={format!("--default-column-title:var(--column-selector-column-{path}--content)")}
377
+ style={format!("--default-column-title:var(--psp-label--column-{path}--content)")}
363
378
  data-index={ctx.props().idx.to_string()}
364
379
  {onmouseover}
365
380
  {onmouseout}
@@ -16,10 +16,10 @@ use itertools::Itertools;
16
16
  use perspective_client::config::*;
17
17
  use yew::prelude::*;
18
18
 
19
- use crate::components::containers::select::*;
20
19
  use crate::renderer::*;
21
20
  use crate::session::*;
22
21
  use crate::tasks::apply_and_render;
22
+ use crate::ui::{Select, SelectItem};
23
23
  use crate::utils::{PtrEqRc, spawn_owned};
24
24
 
25
25
  #[derive(Properties)]
@@ -21,8 +21,7 @@ use super::filter_column::*;
21
21
  use super::pivot_column::*;
22
22
  use super::sort_column::*;
23
23
  use crate::components::column_dropdown::{ColumnDropDownElement, ColumnDropDownPortal};
24
- use crate::components::containers::dragdrop_list::*;
25
- use crate::components::containers::select::{Select, SelectItem};
24
+ use crate::components::dragdrop_list::*;
26
25
  use crate::components::filter_dropdown::{FilterDropDownElement, FilterDropDownPortal};
27
26
  use crate::config::PluginStaticConfig;
28
27
  use crate::presentation::Presentation;
@@ -30,6 +29,7 @@ use crate::renderer::*;
30
29
  use crate::session::drag_drop_update::*;
31
30
  use crate::session::*;
32
31
  use crate::tasks::apply_and_render;
32
+ use crate::ui::{Select, SelectItem};
33
33
  use crate::utils::*;
34
34
 
35
35
  #[derive(Clone, Properties)]