@perspective-dev/viewer 4.5.2 → 5.1.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 (227) hide show
  1. package/dist/cdn/perspective-viewer.js +20 -1
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/botanical.css +1 -1
  4. package/dist/css/dracula.css +1 -1
  5. package/dist/css/gruvbox-dark.css +1 -1
  6. package/dist/css/gruvbox.css +1 -1
  7. package/dist/css/icons.css +1 -1
  8. package/dist/css/intl/de.css +1 -1
  9. package/dist/css/intl/es.css +1 -1
  10. package/dist/css/intl/fr.css +1 -1
  11. package/dist/css/intl/ja.css +1 -1
  12. package/dist/css/intl/pt.css +1 -1
  13. package/dist/css/intl/zh.css +1 -1
  14. package/dist/css/intl.css +1 -1
  15. package/dist/css/monokai.css +1 -1
  16. package/dist/css/phosphor.css +1 -1
  17. package/dist/css/pro-dark.css +1 -1
  18. package/dist/css/pro.css +1 -1
  19. package/dist/css/solarized-dark.css +1 -1
  20. package/dist/css/solarized.css +1 -1
  21. package/dist/css/themes.css +1 -1
  22. package/dist/css/vaporwave.css +1 -1
  23. package/dist/esm/extensions.d.ts +22 -3
  24. package/dist/esm/perspective-viewer.d.ts +9 -0
  25. package/dist/esm/perspective-viewer.inline.js +20 -1
  26. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  27. package/dist/esm/perspective-viewer.js +20 -1
  28. package/dist/esm/perspective-viewer.js.map +4 -4
  29. package/dist/esm/plugin.d.ts +71 -5
  30. package/dist/esm/ts-rs/ClientOptions.d.ts +7 -0
  31. package/dist/esm/ts-rs/ExportMethod.d.ts +1 -0
  32. package/dist/esm/ts-rs/ExportOptions.d.ts +9 -0
  33. package/dist/esm/ts-rs/GetClientOptions.d.ts +8 -0
  34. package/dist/esm/ts-rs/GetTableOptions.d.ts +8 -0
  35. package/dist/esm/ts-rs/Layout.d.ts +11 -0
  36. package/dist/esm/ts-rs/Orientation.d.ts +4 -0
  37. package/dist/esm/ts-rs/PanelOptions.d.ts +7 -0
  38. package/dist/esm/ts-rs/PanelViewerConfig.d.ts +41 -0
  39. package/dist/esm/ts-rs/SplitLayout.d.ts +7 -0
  40. package/dist/esm/ts-rs/TabLayout.d.ts +10 -0
  41. package/dist/esm/ts-rs/ViewerConfig.d.ts +8 -2
  42. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +9 -0
  43. package/dist/esm/ts-rs/WindowAggregate.d.ts +1 -0
  44. package/dist/esm/ts-rs/WindowSort.d.ts +7 -0
  45. package/dist/esm/ts-rs/WindowSortDir.d.ts +6 -0
  46. package/dist/esm/ts-rs/WindowSpec.d.ts +46 -0
  47. package/dist/esm/ts-rs/Windows.d.ts +10 -0
  48. package/dist/esm/ts-rs/WorkspaceConfig.d.ts +40 -0
  49. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +28 -0
  50. package/dist/wasm/perspective-viewer.d.ts +299 -78
  51. package/dist/wasm/perspective-viewer.js +544 -186
  52. package/dist/wasm/perspective-viewer.wasm +0 -0
  53. package/dist/wasm/perspective-viewer.wasm.d.ts +34 -26
  54. package/dist/wasm/snippets/perspective-viewer-8a8c7d5d696b43ae/inline0.js +6 -0
  55. package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline3.js → perspective-viewer-8a8c7d5d696b43ae/inline4.js} +5 -0
  56. package/package.json +3 -2
  57. package/src/css/_context_menu.css +14 -0
  58. package/src/css/column-selector.css +1 -0
  59. package/src/css/column-settings-panel.css +68 -3
  60. package/src/css/column-style.css +4 -3
  61. package/src/css/config-selector.css +22 -1
  62. package/src/css/containers/context-menu.css +107 -0
  63. package/src/css/containers/tabs.css +2 -2
  64. package/src/css/panel-tab.css +193 -0
  65. package/src/css/plugin-selector.css +7 -10
  66. package/src/css/status-bar.css +75 -81
  67. package/src/css/viewer.css +188 -70
  68. package/src/rust/components/column_dropdown.rs +40 -30
  69. package/src/rust/components/column_selector/active_column.rs +28 -45
  70. package/src/rust/components/column_selector/aggregate_selector.rs +4 -7
  71. package/src/rust/components/column_selector/column_selector_column_row.rs +73 -0
  72. package/src/rust/components/column_selector/config_selector.rs +40 -82
  73. package/src/rust/components/column_selector/expr_edit_button.rs +7 -1
  74. package/src/rust/components/column_selector/filter_column.rs +5 -15
  75. package/src/rust/components/column_selector/inactive_column.rs +11 -9
  76. package/src/rust/components/column_selector/sort_column.rs +3 -6
  77. package/src/rust/components/column_selector.rs +25 -14
  78. package/src/rust/components/column_settings_sidebar/style_tab.rs +2 -1
  79. package/src/rust/components/column_settings_sidebar/window_tab.rs +34 -0
  80. package/src/rust/components/column_settings_sidebar.rs +163 -16
  81. package/src/rust/components/containers/dragdrop_list.rs +73 -3
  82. package/src/rust/components/containers/sidebar.rs +99 -22
  83. package/src/rust/components/containers/split_panel.rs +181 -62
  84. package/src/rust/components/context_menu.rs +130 -0
  85. package/src/rust/components/editable_header.rs +2 -0
  86. package/src/rust/components/form/debug.rs +3 -0
  87. package/src/rust/components/global_filter_bar.rs +76 -0
  88. package/src/rust/components/main_panel/frame_theme.rs +186 -0
  89. package/src/rust/components/main_panel/msg.rs +62 -0
  90. package/src/rust/components/main_panel/presize.rs +220 -0
  91. package/src/rust/components/main_panel/reconcile.rs +224 -0
  92. package/src/rust/components/main_panel/render.rs +385 -0
  93. package/src/rust/components/main_panel/update.rs +184 -0
  94. package/src/rust/components/main_panel.rs +316 -71
  95. package/src/rust/components/mod.rs +5 -0
  96. package/src/rust/components/panel_menu.rs +493 -0
  97. package/src/rust/components/panel_tab.rs +510 -0
  98. package/src/rust/components/plugin_tab.rs +1 -1
  99. package/src/rust/components/portal.rs +7 -0
  100. package/src/rust/components/settings_panel.rs +13 -5
  101. package/src/rust/components/status_bar.rs +110 -178
  102. package/src/rust/components/status_indicator.rs +6 -9
  103. package/src/rust/components/style/mod.rs +5 -0
  104. package/src/rust/components/style/style_provider.rs +2 -0
  105. package/src/rust/components/viewer/filters.rs +133 -0
  106. package/src/rust/components/viewer/msg.rs +182 -0
  107. package/src/rust/components/viewer/panels.rs +326 -0
  108. package/src/rust/components/viewer/render.rs +255 -0
  109. package/src/rust/components/viewer/settings.rs +434 -0
  110. package/src/rust/components/viewer/snapshots.rs +134 -0
  111. package/src/rust/components/viewer/wiring.rs +505 -0
  112. package/src/rust/components/viewer.rs +245 -756
  113. package/src/rust/components/window_editor.rs +1013 -0
  114. package/src/rust/config/export_method.rs +1 -1
  115. package/src/rust/config/mod.rs +4 -0
  116. package/src/rust/config/options.rs +71 -0
  117. package/src/rust/config/viewer_config.rs +24 -2
  118. package/src/rust/config/workspace_config.rs +92 -0
  119. package/src/rust/custom_elements/copy_dropdown.rs +3 -1
  120. package/src/rust/custom_elements/debug_plugin.rs +20 -1
  121. package/src/rust/custom_elements/export_dropdown.rs +3 -1
  122. package/src/rust/custom_elements/viewer.rs +1015 -286
  123. package/src/rust/custom_events.rs +212 -61
  124. package/src/rust/js/mod.rs +2 -0
  125. package/src/rust/js/plugin.rs +297 -10
  126. package/src/rust/js/regular_layout.rs +258 -0
  127. package/src/rust/lib.rs +24 -2
  128. package/src/rust/presentation/column_locator.rs +16 -1
  129. package/src/rust/presentation.rs +66 -33
  130. package/src/rust/queries/columns_iter_set.rs +7 -1
  131. package/src/rust/queries/get_viewer_config.rs +29 -11
  132. package/src/rust/queries/plugin_column_styles.rs +2 -2
  133. package/src/rust/renderer/activate.rs +41 -14
  134. package/src/rust/renderer/dispatch.rs +463 -0
  135. package/src/rust/renderer/plugin_config.rs +495 -0
  136. package/src/rust/renderer/registry.rs +18 -6
  137. package/src/rust/renderer/render_timer.rs +29 -10
  138. package/src/rust/renderer.rs +384 -838
  139. package/src/rust/session/column_defaults_update.rs +26 -8
  140. package/src/rust/session/drag_drop_update.rs +18 -0
  141. package/src/rust/session/metadata.rs +66 -9
  142. package/src/rust/session/replace_expression_update.rs +1 -0
  143. package/src/rust/session/view_subscription.rs +30 -15
  144. package/src/rust/session.rs +755 -264
  145. package/src/rust/tasks/apply_global_filters.rs +89 -0
  146. package/src/rust/tasks/auto_pause.rs +171 -0
  147. package/src/rust/tasks/copy_export.rs +29 -19
  148. package/src/rust/tasks/create_panel.rs +243 -0
  149. package/src/rust/tasks/dismiss_render_warning.rs +3 -1
  150. package/src/rust/tasks/edit_expression.rs +4 -4
  151. package/src/rust/tasks/edit_window.rs +155 -0
  152. package/src/rust/tasks/eject.rs +64 -23
  153. package/src/rust/tasks/mod.rs +30 -4
  154. package/src/rust/tasks/pipeline.rs +411 -0
  155. package/src/rust/tasks/presize_panels.rs +324 -0
  156. package/src/rust/tasks/reset_all.rs +22 -12
  157. package/src/rust/tasks/resize_observer.rs +124 -87
  158. package/src/rust/tasks/restore_and_render.rs +80 -86
  159. package/src/rust/tasks/restore_panel.rs +145 -0
  160. package/src/rust/tasks/send_column_config.rs +5 -2
  161. package/src/rust/tasks/send_plugin_config.rs +5 -2
  162. package/src/rust/tasks/set_edit_mode.rs +59 -0
  163. package/src/rust/tasks/sync_update_panels.rs +152 -0
  164. package/src/rust/tasks/table_lifecycle.rs +158 -0
  165. package/src/rust/tasks/update_theme.rs +56 -12
  166. package/src/rust/utils/browser/dragdrop.rs +12 -0
  167. package/src/rust/utils/browser/tests/debounce.rs +49 -0
  168. package/src/rust/utils/completion.rs +56 -0
  169. package/src/rust/utils/custom_element.rs +5 -0
  170. package/src/rust/utils/debounce.rs +189 -17
  171. package/src/rust/utils/mod.rs +6 -0
  172. package/src/rust/utils/pending_effects.rs +62 -0
  173. package/src/rust/utils/spawn.rs +33 -0
  174. package/src/rust/utils/weak_scope.rs +0 -10
  175. package/src/rust/workspace.rs +846 -0
  176. package/src/svg/active-indicator.svg +3 -0
  177. package/src/svg/pin-icon.svg +5 -0
  178. package/src/themes/botanical.css +5 -2
  179. package/src/themes/defaults.css +54 -2
  180. package/src/themes/dracula.css +6 -3
  181. package/src/themes/gruvbox-dark.css +5 -2
  182. package/src/themes/gruvbox.css +5 -2
  183. package/src/themes/icons.css +5 -2
  184. package/src/themes/intl/de.css +7 -0
  185. package/src/themes/intl/es.css +7 -0
  186. package/src/themes/intl/fr.css +7 -0
  187. package/src/themes/intl/ja.css +7 -0
  188. package/src/themes/intl/pt.css +7 -0
  189. package/src/themes/intl/zh.css +7 -0
  190. package/src/themes/intl.css +10 -1
  191. package/src/themes/monokai.css +5 -2
  192. package/src/themes/phosphor.css +5 -2
  193. package/src/themes/pro-dark.css +5 -2
  194. package/src/themes/pro.css +2 -1
  195. package/src/themes/solarized-dark.css +5 -2
  196. package/src/themes/solarized.css +5 -2
  197. package/src/themes/vaporwave.css +5 -2
  198. package/src/ts/bootstrap.ts +8 -7
  199. package/src/ts/extensions.ts +30 -2
  200. package/src/ts/perspective-viewer.ts +10 -0
  201. package/src/ts/plugin.ts +72 -5
  202. package/src/ts/ts-rs/ClientOptions.ts +7 -0
  203. package/src/ts/ts-rs/ExportMethod.ts +3 -0
  204. package/src/ts/ts-rs/ExportOptions.ts +8 -0
  205. package/src/ts/ts-rs/GetClientOptions.ts +7 -0
  206. package/src/ts/ts-rs/GetTableOptions.ts +7 -0
  207. package/src/ts/ts-rs/Layout.ts +9 -0
  208. package/src/ts/ts-rs/Orientation.ts +6 -0
  209. package/src/ts/ts-rs/PanelOptions.ts +7 -0
  210. package/src/ts/ts-rs/PanelViewerConfig.ts +16 -0
  211. package/src/ts/ts-rs/SplitLayout.ts +5 -0
  212. package/src/ts/ts-rs/TabLayout.ts +11 -0
  213. package/src/ts/ts-rs/ViewerConfig.ts +7 -2
  214. package/src/ts/ts-rs/ViewerConfigUpdate.ts +9 -0
  215. package/src/ts/ts-rs/WindowAggregate.ts +3 -0
  216. package/src/ts/ts-rs/WindowSort.ts +9 -0
  217. package/src/ts/ts-rs/WindowSortDir.ts +8 -0
  218. package/src/ts/ts-rs/WindowSpec.ts +46 -0
  219. package/src/ts/ts-rs/Windows.ts +10 -0
  220. package/src/ts/ts-rs/WorkspaceConfig.ts +36 -0
  221. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +24 -0
  222. package/src/rust/tasks/intersection_observer.rs +0 -98
  223. package/src/rust/tasks/update_and_render.rs +0 -110
  224. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline0.js → perspective-viewer-8a8c7d5d696b43ae/inline1.js} +0 -0
  225. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline1.js → perspective-viewer-8a8c7d5d696b43ae/inline2.js} +0 -0
  226. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline2.js → perspective-viewer-8a8c7d5d696b43ae/inline3.js} +0 -0
  227. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline4.js → perspective-viewer-8a8c7d5d696b43ae/inline5.js} +0 -0
@@ -20,7 +20,7 @@
20
20
  #plugin_selector_container {
21
21
  min-height: var(
22
22
  --psp-plugin-selector--height,
23
- var(--psp-status-bar--height, 48px)
23
+ var(--psp-status-bar--height, 38px)
24
24
  );
25
25
  display: flex;
26
26
  white-space: nowrap;
@@ -48,6 +48,7 @@
48
48
  &.open {
49
49
  position: absolute;
50
50
  margin: 0;
51
+ margin-left: -1px;
51
52
  top: 0;
52
53
  left: 0;
53
54
  right: 0;
@@ -58,15 +59,11 @@
58
59
  z-index: 3;
59
60
  color: var(--psp--color, #042121);
60
61
  /* background: var(--psp--background-color); */
61
-
62
- .plugin-select-item {
63
- padding-left: 8px;
64
- }
65
62
  }
66
63
 
67
64
  .plugin-select-item-name {
68
- padding-left: 10px;
69
- font-size: 1.33333em;
65
+ padding-left: 4px;
66
+ font-size: 1.1em;
70
67
  }
71
68
 
72
69
  .plugin-select-item-name:before {
@@ -76,14 +73,14 @@
76
73
 
77
74
  .plugin-select-item {
78
75
  /* width: 48px; */
79
- padding-left: 9px;
76
+ padding-left: 5px;
80
77
  height: var(
81
78
  --psp-plugin-selector--height,
82
- var(--psp-status-bar--height, 48px)
79
+ var(--psp-status-bar--height, 38px)
83
80
  );
84
81
  min-height: var(
85
82
  --psp-plugin-selector--height,
86
- var(--psp-status-bar--height, 48px)
83
+ var(--psp-status-bar--height, 38px)
87
84
  );
88
85
  display: flex;
89
86
  align-items: center;
@@ -19,15 +19,8 @@
19
19
  }
20
20
 
21
21
  :host {
22
- /* When settings open ... */
23
- #main_column #status_bar,
24
- #main_column #status_bar.titled {
25
- input::placeholder {
26
- color: var(--psp-inactive--color);
27
- }
28
- }
29
-
30
22
  #status_bar.settings-closed {
23
+ box-shadow: none;
31
24
  padding-right: 10px;
32
25
  }
33
26
 
@@ -43,86 +36,25 @@
43
36
  height: auto;
44
37
  min-height: auto;
45
38
  max-height: none;
46
- gap: 6px;
47
- top: calc((var(--psp-status-bar--height, 48px) - 20px) / 2);
39
+ top: calc((var(--psp-status-bar--height, 38px) - 20px) / 2);
48
40
  right: calc(
49
- min(48px, (var(--psp-status-bar--height, 48px) - 20px) / 2)
41
+ min(48px, (var(--psp-status-bar--height, 38px) - 20px) / 2)
50
42
  );
51
43
  }
52
44
 
53
45
  #status_bar {
54
- box-shadow: 0 13px 0 -12px var(--psp-inactive--border-color);
55
- z-index: 3;
46
+ box-shadow: 0 1px 0 0px var(--psp-inactive--color);
47
+ z-index: 6;
56
48
  display: var(--psp-status-bar--display, flex);
57
- gap: 6px;
49
+ gap: 4px;
58
50
  align-items: center;
59
51
  background: var(--psp--background-color);
60
- padding: var(--psp-status-bar--padding, 0 31px 0 8px);
52
+ padding: var(--psp-status-bar--padding, 0 31px 0 4px);
61
53
  position: relative;
62
- height: var(--psp-status-bar--height, 48px);
63
- min-height: var(--psp-status-bar--height, 48px);
64
- max-height: var(--psp-status-bar--height, 48px);
54
+ height: var(--psp-status-bar--height, 38px);
55
+ min-height: var(--psp-status-bar--height, 38px);
56
+ max-height: var(--psp-status-bar--height, 38px);
65
57
  border-radius: var(--psp-status-bar--border-radius);
66
- #status-bar-placeholder {
67
- margin: 0px;
68
- margin-right: -5px;
69
- pointer-events: none;
70
- }
71
-
72
- input {
73
- font-size: 1em;
74
- }
75
-
76
- input:placeholder-shown + #status-bar-placeholder:before {
77
- content: var(--psp-label--untitled--content, "untitled");
78
- color: var(--psp-inactive--color);
79
- }
80
-
81
- .input-sizer {
82
- display: inline-block;
83
- align-items: center;
84
- position: relative;
85
- min-width: 65px;
86
- overflow: hidden;
87
- padding-top: 0.5px;
88
-
89
- &:after,
90
- input,
91
- textarea {
92
- width: auto;
93
- grid-area: 1 / 1;
94
- font-family: inherit;
95
- }
96
-
97
- input,
98
- textarea {
99
- position: absolute;
100
- left: 0;
101
- right: 0;
102
- text-overflow: ellipsis;
103
- padding: 0;
104
- border: none;
105
- background: transparent;
106
- color: inherit;
107
- height: 100%;
108
- }
109
-
110
- &:after {
111
- content: attr(data-value) " ";
112
- color: var(--psp-inactive--color, inherit);
113
- visibility: hidden;
114
- white-space: nowrap;
115
- padding-right: 12px;
116
- }
117
-
118
- &:focus-within {
119
- textarea:focus,
120
- input:focus {
121
- outline: none;
122
- }
123
- }
124
- }
125
-
126
58
  .section {
127
59
  display: flex;
128
60
  align-items: center;
@@ -143,7 +75,7 @@
143
75
  gap: 6px;
144
76
  flex: 0 1000 auto;
145
77
  overflow: hidden;
146
- margin: 0px 10px;
78
+ margin: 0px 0px;
147
79
  pointer-events: none;
148
80
  span {
149
81
  margin: 0 !important;
@@ -166,6 +98,68 @@
166
98
  align-self: stretch;
167
99
  }
168
100
 
101
+ /* Global-filter chips, rendered inline between the row stats and the
102
+ menu icons (was a dedicated strip above the panels). Shrinks/clips
103
+ rather than growing the fixed-height bar. */
104
+ #global_filter_bar {
105
+ display: flex;
106
+ align-items: center;
107
+ gap: 6px;
108
+ flex: 0 1 auto;
109
+ min-width: 0;
110
+ overflow: hidden;
111
+ font-size: 11px;
112
+
113
+ /* Beat the status bar's generic `span { margin: 0 14px }`. */
114
+ span {
115
+ margin: 0;
116
+ }
117
+
118
+ .global-filter-bar-label {
119
+ opacity: 0.6;
120
+ pointer-events: none;
121
+ }
122
+
123
+ .global-filter-bar-chips {
124
+ display: flex;
125
+ align-items: center;
126
+ gap: 4px;
127
+ min-width: 0;
128
+ overflow: hidden;
129
+ }
130
+
131
+ .global-filter-chip {
132
+ display: inline-flex;
133
+ align-items: center;
134
+ gap: 4px;
135
+ padding: 1px 4px 1px 6px;
136
+ background: var(--psp--background-color, #ffffff);
137
+ border: 1px solid var(--psp-inactive--color, #c8ccd0);
138
+ border-radius: 3px;
139
+ white-space: nowrap;
140
+ }
141
+
142
+ .global-filter-chip-remove {
143
+ cursor: pointer;
144
+ opacity: 0.5;
145
+ font-size: 13px;
146
+ line-height: 1;
147
+ }
148
+
149
+ .global-filter-chip-remove:hover {
150
+ opacity: 1;
151
+ }
152
+
153
+ .global-filter-bar-clear {
154
+ cursor: pointer;
155
+ opacity: 0.6;
156
+ }
157
+
158
+ .global-filter-bar-clear:hover {
159
+ opacity: 1;
160
+ }
161
+ }
162
+
169
163
  span {
170
164
  white-space: nowrap;
171
165
  margin: 0px 14px;
@@ -243,8 +237,8 @@
243
237
  align-items: center;
244
238
  display: flex;
245
239
  padding-right: 17px;
246
- height: var(--psp-status-bar--height, 48px);
247
- min-height: var(--psp-status-bar--height, 48px);
240
+ height: var(--psp-status-bar--height, 38px);
241
+ min-height: var(--psp-status-bar--height, 38px);
248
242
  }
249
243
 
250
244
  .error-dialog-stack {
@@ -16,10 +16,6 @@
16
16
  --psp--color: #ff0000;
17
17
  }
18
18
 
19
- /* Shift-key affordance: while the user holds Shift, any mask-image icon
20
- * tagged `.shift-alt-icon` recolors to advertise that a Shift-modified
21
- * action is available on the underlying control. `!important` is required
22
- * to beat per-icon ID-scoped `background-color` rules. */
23
19
  :host(.shift-active) .shift-alt-icon {
24
20
  background-color: var(
25
21
  --shift-active--color,
@@ -93,8 +89,44 @@
93
89
  pointer-events: var(--override-content-pointer-events);
94
90
  }
95
91
 
92
+ ::slotted(:not([slot^="statusbar-extra"]):not([slot^="tab-"])) {
93
+ position: absolute;
94
+ inset: 0;
95
+ background-color: var(--psp--background-color) !important;
96
+ box-shadow:
97
+ 2.25px 2.25px 0 2.25px var(--psp--background-color),
98
+ /* down-right */ -2.25px 2.25px 0 2.25px var(--psp--background-color),
99
+ /* down-left */ 2.75px 2.75px 0 2.75px var(--psp-inactive--color),
100
+ -1.75px 2.75px 0 2.75px var(--psp-inactive--color);
101
+ }
102
+
103
+ .overlay ::slotted(:not([slot^="statusbar-extra"]):not([slot^="tab-"])) {
104
+ box-shadow:
105
+ 2.25px 2.25px 0 2.25px var(--psp--background-color),
106
+ -2.25px 2.25px 0 2.25px var(--psp--background-color),
107
+ 2.75px 2.75px 0 2.75px var(--psp-inactive--color),
108
+ -2.75px 2.75px 0 2.75px var(--psp-inactive--color);
109
+ }
110
+
111
+ ::slotted([part="tab"].visible) {
112
+ box-shadow:
113
+ 2.25px -2.25px 0 2.25px var(--psp--background-color),
114
+ -2.25px -2.25px 0 2.25px var(--psp--background-color),
115
+ 3.5px -2.25px 0 2.25px var(--psp-inactive--color),
116
+ 0 12.5px 0 -11.5px var(--psp-inactive--border-color);
117
+ }
118
+
119
+ .overlay ::slotted([part="tab"].visible) {
120
+ box-shadow:
121
+ 2.25px -2.25px 0 2.25px var(--psp--background-color),
122
+ -2.25px -2.25px 0 2.25px var(--psp--background-color),
123
+ 2.75px -2.75px 0 2.75px var(--psp-inactive--color),
124
+ -2.75px -2.75px 0 2.75px var(--psp-inactive--color),
125
+ 0 12.5px 0 -11.5px var(--psp-inactive--border-color);
126
+ }
127
+
96
128
  :host input[type="number"]::-webkit-inner-spin-button {
97
- transform: scale(1.5) translateX(-5px); /* Makes the arrows 50% larger */
129
+ transform: scale(1.5) translateX(-5px);
98
130
  filter: var(--psp-input--filter);
99
131
  }
100
132
 
@@ -105,7 +137,7 @@
105
137
  (
106
138
  var(
107
139
  --psp-plugin-selector--height,
108
- var(--psp-status-bar--height, 48px)
140
+ var(--psp-status-bar--height, 38px)
109
141
  ) -
110
142
  20px
111
143
  ) /
@@ -115,7 +147,7 @@
115
147
  (
116
148
  var(
117
149
  --psp-plugin-selector--height,
118
- var(--psp-status-bar--height, 48px)
150
+ var(--psp-status-bar--height, 38px)
119
151
  ) -
120
152
  20px
121
153
  ) /
@@ -124,7 +156,7 @@
124
156
  z-index: 10000;
125
157
  height: var(
126
158
  --psp-plugin-selector--height,
127
- var(--psp-status-bar--height, 48px)
159
+ var(--psp-status-bar--height, 38px)
128
160
  );
129
161
 
130
162
  &:hover {
@@ -212,11 +244,6 @@
212
244
  #menu-bar {
213
245
  opacity: 1 !important;
214
246
  }
215
-
216
- #component_container #settings_button,
217
- #component_container #settings_button.titled {
218
- opacity: 1;
219
- }
220
247
  }
221
248
 
222
249
  :host {
@@ -241,6 +268,14 @@
241
268
  flex-direction: column;
242
269
  }
243
270
 
271
+ #layout_area {
272
+ flex: 1 1 auto;
273
+ position: relative;
274
+ min-height: 0;
275
+ display: flex;
276
+ overflow: hidden;
277
+ }
278
+
244
279
  #app_panel {
245
280
  position: absolute;
246
281
  bottom: 0px;
@@ -268,13 +303,21 @@
268
303
  }
269
304
  }
270
305
 
306
+ #modal_panel.pinned {
307
+ position: static;
308
+ flex: 0 0 auto;
309
+ width: auto;
310
+ pointer-events: all;
311
+ overflow: visible;
312
+ }
313
+
271
314
  #modal_panel > .split-panel-divider {
272
315
  border-left: 1px solid var(--psp-inactive--color, #6e6e6e);
273
316
  margin-right: -5px;
274
317
  }
275
318
 
276
319
  #status_bar {
277
- height: var(--psp-status-bar--height, 48px);
320
+ height: var(--psp-status-bar--height, 38px);
278
321
  }
279
322
 
280
323
  #main_column_container {
@@ -297,15 +340,142 @@
297
340
  }
298
341
 
299
342
  #main_panel_container {
343
+ z-index: 0;
300
344
  position: relative;
301
345
  height: 100%;
302
346
  box-shadow: var(--plugin--box-shadow, none);
347
+ overflow: hidden;
348
+ border: var(--psp-plugin--border, none);
303
349
  background: var(
304
350
  --psp-main-column--background,
305
351
  var(--psp--background-color, none)
306
352
  );
307
- overflow: hidden;
308
- border: var(--psp-plugin--border, none);
353
+
354
+ /* A STAGED panel's hidden staging wrapper (`MainPanel::render` +
355
+ `Workspace::stage_panel`): a freshly-created panel's plugin
356
+ completes its first draw here, laid out at predicted final size
357
+ but unpainted. `visibility` (not `display`) so the plugin keeps a
358
+ real box and a non-null `offsetParent` — draw guards, redraw
359
+ subscriptions and observers behave exactly as for a visible
360
+ panel. */
361
+ & > .psp-staging {
362
+ position: absolute;
363
+ top: 0;
364
+ left: 0;
365
+ overflow: hidden;
366
+ visibility: hidden;
367
+ pointer-events: none;
368
+ }
369
+
370
+ & > .psp-staging ::slotted(*) {
371
+ display: block;
372
+ width: 100%;
373
+ height: 100%;
374
+ }
375
+
376
+ /* The layout engine hosting this panel's plugin fills the container. */
377
+ & regular-layout {
378
+ position: absolute;
379
+ inset: -4px -4px -4px -4px;
380
+ box-sizing: border-box;
381
+ padding: 0px;
382
+ background: var(--psp--background-color, transparent);
383
+
384
+ & > .rl-panel {
385
+ position: relative;
386
+ box-sizing: border-box;
387
+ background: none;
388
+ border: 1px solid transparent;
389
+ margin: var(--psp-panel--margin, 4px);
390
+ }
391
+
392
+ & > .rl-panel::part(container) {
393
+ position: relative;
394
+ background: var(--psp--background-color);
395
+ /* box-shadow: 0 0 0 4.5px var(--psp--background-color); */
396
+ }
397
+
398
+ & > .rl-panel::part(titlebar-track) {
399
+ gap: 10px;
400
+ }
401
+
402
+ & > .rl-panel::part(titlebar) {
403
+ display: flex;
404
+ align-items: stretch;
405
+ height: var(--psp-panel-titlebar--height, 26px);
406
+ font-family: var(--button--font-family, inherit);
407
+ overflow: visible;
408
+ }
409
+
410
+ & > .rl-panel::part(tab) {
411
+ display: flex;
412
+ flex: 1 1 auto;
413
+ align-items: center;
414
+ min-width: 0;
415
+ padding: 0 8px;
416
+ cursor: pointer;
417
+ font-size: 11px;
418
+ white-space: nowrap;
419
+ color: var(--psp--color, inherit);
420
+ background: var(--psp--background-color, #ffffff);
421
+ }
422
+
423
+ & > .rl-panel::part(title) {
424
+ overflow: hidden;
425
+ text-overflow: ellipsis;
426
+ }
427
+
428
+ & > .rl-panel::part(close) {
429
+ flex: 0 0 auto;
430
+ align-self: center;
431
+ display: flex;
432
+ align-items: center;
433
+ justify-content: center;
434
+ width: 16px;
435
+ height: 16px;
436
+ margin: 0 4px;
437
+ border: none;
438
+ background: none;
439
+ cursor: pointer;
440
+ opacity: 0.6;
441
+ color: inherit;
442
+ }
443
+
444
+ & > .rl-panel::part(close):hover {
445
+ opacity: 1;
446
+ }
447
+
448
+ & > .rl-panel::part(close):before {
449
+ content: "×";
450
+ font-size: 14px;
451
+ line-height: 1;
452
+ }
453
+
454
+ & > .rl-panel.single::part(close) {
455
+ display: none;
456
+ }
457
+
458
+ &:has(.overlay) > * {
459
+ opacity: 0.7;
460
+ }
461
+
462
+ &:has(.overlay) > .overlay {
463
+ opacity: 1;
464
+ }
465
+
466
+ & > .overlay {
467
+ /* background: var(
468
+ --psp-panel-overlay--background,
469
+ rgba(26, 125, 161, 0.15)
470
+ ); */
471
+
472
+ transition:
473
+ top 0.1s ease-in-out,
474
+ left 0.1s ease-in-out,
475
+ width 0.1s ease-in-out,
476
+ height 0.1s ease-in-out;
477
+ }
478
+ }
309
479
  }
310
480
 
311
481
  #settings_panel {
@@ -367,15 +537,6 @@
367
537
  border-right-width: 0px;
368
538
  }
369
539
 
370
- #component_container > #settings_button {
371
- opacity: 0;
372
- position: absolute;
373
- top: 0;
374
- right: 0;
375
- margin: var(--settings-button--margin, 10px 36px 0 0);
376
- padding: 0;
377
- }
378
-
379
540
  #close_button {
380
541
  background-color: var(--psp--background-color);
381
542
  padding: 0px;
@@ -388,7 +549,6 @@
388
549
  border-radius: 5px;
389
550
  font-size: 10px;
390
551
  font-weight: normal;
391
-
392
552
  &:hover {
393
553
  color: var(--psp--background-color, inherit);
394
554
  background-color: var(--psp--color);
@@ -415,49 +575,6 @@
415
575
  }
416
576
  }
417
577
 
418
- #settings_button {
419
- background-color: var(--psp--background-color);
420
- padding: 0;
421
- overflow: hidden;
422
- display: flex;
423
- align-items: center;
424
- justify-content: center;
425
- z-index: 3;
426
- border: 1px solid var(--psp-inactive--color);
427
- border-radius: 5px;
428
- font-size: 10px;
429
- font-weight: normal;
430
-
431
- &:hover {
432
- color: var(--psp--background-color, inherit);
433
- background-color: var(--psp--color);
434
- cursor: pointer;
435
- }
436
-
437
- &:hover .icon {
438
- background-color: var(--psp--background-color);
439
- }
440
-
441
- .icon {
442
- display: inline-flex;
443
- mask-size: cover;
444
- -webkit-mask-size: cover;
445
- background-repeat: no-repeat;
446
- background-color: var(--psp--color);
447
- mask-image: var(--psp-icon--drawer-tab-inverted--mask-image);
448
- -webkit-mask-image: var(
449
- --psp-icon--drawer-tab-inverted--mask-image
450
- );
451
-
452
- &:before {
453
- line-height: 0;
454
- display: inline-flex;
455
- content: var(--psp-icon--drawer-tab-inverted--mask-image);
456
- visibility: hidden;
457
- }
458
- }
459
- }
460
-
461
578
  .settings_tab_bar_scroll_offset {
462
579
  margin-left: -8px;
463
580
  }
@@ -506,10 +623,11 @@
506
623
  min-height: calc(
507
624
  var(
508
625
  --psp-plugin-selector--height,
509
- var(--psp-status-bar--height, 48px)
626
+ var(--psp-status-bar--height, 38px)
510
627
  ) +
511
628
  1px
512
629
  );
630
+ z-index: 7;
513
631
  overflow: hidden;
514
632
  display: flex;
515
633
  flex-direction: column;
@@ -70,50 +70,60 @@ impl ColumnDropDownElement {
70
70
  callback: Callback<InPlaceColumn>,
71
71
  ) -> Option<()> {
72
72
  let input = target.value();
73
- let metadata = self.session.metadata();
74
- let mut values: Vec<InPlaceColumn> = vec![];
75
73
  let small_input = input.to_lowercase();
76
- for col in metadata.get_table_columns()? {
77
- if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
78
- values.push(InPlaceColumn::Column(col.to_owned()));
74
+ let mut values: Vec<InPlaceColumn> = vec![];
75
+ {
76
+ let metadata = self.session.metadata();
77
+ for col in metadata.get_table_columns()? {
78
+ if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
79
+ values.push(InPlaceColumn::Column(col.to_owned()));
80
+ }
79
81
  }
80
- }
81
82
 
82
- for col in self.session.metadata().get_expression_columns() {
83
- if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
84
- values.push(InPlaceColumn::Column(col.to_owned()));
83
+ for col in metadata.get_expression_columns() {
84
+ if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
85
+ values.push(InPlaceColumn::Column(col.to_owned()));
86
+ }
85
87
  }
86
88
  }
87
89
 
88
- clone!(self.state, self.session, self.notify);
89
- let target_elem: HtmlElement = target.clone().into();
90
90
  let width = target.get_bounding_client_rect().width();
91
- ApiFuture::spawn(async move {
92
- if !exclude.contains(&input) {
91
+ let target_elem: HtmlElement = target.clone().into();
92
+
93
+ // Publish the synchronous matches immediately, *before* any async
94
+ // work, so the dropdown and `item_select` always reflect the latest
95
+ // keystroke rather than whichever async continuation happens to
96
+ // resolve last.
97
+ {
98
+ let mut s = self.state.borrow_mut();
99
+ s.values = values;
100
+ s.selected = 0;
101
+ s.width = width;
102
+ s.on_select = Some(callback);
103
+ s.target = Some(target_elem);
104
+ s.no_results = s.values.is_empty();
105
+ }
106
+ self.notify.emit(());
107
+
108
+ if !exclude.contains(&input) {
109
+ clone!(self.state, self.session, self.notify);
110
+ ApiFuture::spawn(async move {
93
111
  let is_expr = crate::queries::validate_expr(&session, &input)
94
112
  .await?
95
113
  .is_none();
96
- if is_expr {
97
- values.push(InPlaceColumn::Expression(Expression::new(
114
+ if is_expr && target.value() == input {
115
+ let mut s = state.borrow_mut();
116
+ s.values.push(InPlaceColumn::Expression(Expression::new(
98
117
  None,
99
118
  input.into(),
100
119
  )));
120
+ s.no_results = false;
121
+ drop(s);
122
+ notify.emit(());
101
123
  }
102
- }
103
-
104
- let no_results = values.is_empty();
105
- {
106
- let mut s = state.borrow_mut();
107
- s.values = values;
108
- s.selected = 0;
109
- s.width = width;
110
- s.on_select = Some(callback);
111
- s.target = Some(target_elem);
112
- s.no_results = no_results;
113
- }
114
- notify.emit(());
115
- Ok(())
116
- });
124
+ Ok(())
125
+ });
126
+ }
117
127
 
118
128
  Some(())
119
129
  }