flexdesk 0.17.8 → 0.17.10

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 (283) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +0 -0
  3. package/README.md +0 -0
  4. package/THIRD_PARTY_LICENSES.md +0 -0
  5. package/canvas.js +0 -0
  6. package/charts.js +0 -0
  7. package/core.js +0 -0
  8. package/css/base.css +78 -56
  9. package/css/flexdesk.css +111 -89
  10. package/css/overrides.css +12 -12
  11. package/css/reset.css +0 -0
  12. package/css/tokens.css +11 -2
  13. package/dist/canvas.js +0 -0
  14. package/dist/canvas.js.map +0 -0
  15. package/dist/charts.js +7 -6
  16. package/dist/charts.js.map +2 -2
  17. package/dist/{chunk-EIYNF4BD.js → chunk-2YTM3GJE.js} +2 -2
  18. package/dist/chunk-2YTM3GJE.js.map +7 -0
  19. package/dist/chunk-3PHCPZHT.js +0 -0
  20. package/dist/chunk-3PHCPZHT.js.map +0 -0
  21. package/dist/{chunk-UURZ37SD.js → chunk-7U4IB65H.js} +27 -9
  22. package/dist/chunk-7U4IB65H.js.map +7 -0
  23. package/dist/{chunk-D3COLZZ2.js → chunk-BE2PU3LL.js} +2 -2
  24. package/dist/{chunk-D3COLZZ2.js.map → chunk-BE2PU3LL.js.map} +0 -0
  25. package/dist/chunk-CVMCZZX2.js +0 -0
  26. package/dist/chunk-CVMCZZX2.js.map +0 -0
  27. package/dist/{chunk-UWO43BZU.js → chunk-F35XSQWA.js} +16 -20
  28. package/dist/chunk-F35XSQWA.js.map +7 -0
  29. package/dist/chunk-FOOS3T5L.js +0 -0
  30. package/dist/chunk-FOOS3T5L.js.map +0 -0
  31. package/dist/chunk-GOQLR5WR.js +0 -0
  32. package/dist/chunk-GOQLR5WR.js.map +0 -0
  33. package/dist/chunk-HNU6MM2B.js +0 -0
  34. package/dist/chunk-HNU6MM2B.js.map +0 -0
  35. package/dist/chunk-JKZLNKG6.js +0 -0
  36. package/dist/chunk-JKZLNKG6.js.map +0 -0
  37. package/dist/chunk-JYWURG5T.js +0 -0
  38. package/dist/chunk-JYWURG5T.js.map +0 -0
  39. package/dist/{chunk-RKNFBX5K.js → chunk-MIW7D6WC.js} +16 -4
  40. package/dist/{chunk-RKNFBX5K.js.map → chunk-MIW7D6WC.js.map} +2 -2
  41. package/dist/chunk-N7HC3ADV.js +0 -0
  42. package/dist/chunk-N7HC3ADV.js.map +0 -0
  43. package/dist/{chunk-LWV23YVE.js → chunk-NIJEJAZ7.js} +42 -18
  44. package/dist/chunk-NIJEJAZ7.js.map +7 -0
  45. package/dist/{chunk-HYJYYEPK.js → chunk-REJ5HLIM.js} +2 -2
  46. package/dist/{chunk-HYJYYEPK.js.map → chunk-REJ5HLIM.js.map} +0 -0
  47. package/dist/{chunk-WVFGV5FT.js → chunk-WUFLGETN.js} +39 -2
  48. package/dist/{chunk-WVFGV5FT.js.map → chunk-WUFLGETN.js.map} +3 -3
  49. package/dist/core.js +0 -0
  50. package/dist/core.js.map +0 -0
  51. package/dist/editor.js +2 -2
  52. package/dist/editor.js.map +0 -0
  53. package/dist/flexdesk.css +111 -89
  54. package/dist/flow.js +3 -3
  55. package/dist/flow.js.map +0 -0
  56. package/dist/host.js +0 -0
  57. package/dist/host.js.map +0 -0
  58. package/dist/reset.css +0 -0
  59. package/dist/tile_registry-6WZPTUZV.js +0 -0
  60. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  61. package/dist/tiles.js +63 -20
  62. package/dist/tiles.js.map +2 -2
  63. package/dist/tokens.css +11 -2
  64. package/dist/widgets.js +6 -6
  65. package/dist/widgets.js.map +0 -0
  66. package/dist/wm.js +5 -5
  67. package/dist/wm.js.map +0 -0
  68. package/docs/README.md +0 -0
  69. package/docs/best-practices.md +0 -0
  70. package/docs/components/charts.md +29 -0
  71. package/docs/components/command-palette.md +0 -0
  72. package/docs/components/conversation.md +0 -0
  73. package/docs/components/data-table-grid.md +0 -0
  74. package/docs/components/data-table.md +0 -0
  75. package/docs/components/editor.md +0 -0
  76. package/docs/components/flow-canvas-editor.md +0 -0
  77. package/docs/components/flow-editors.md +0 -0
  78. package/docs/components/flow-lane-editor.md +0 -0
  79. package/docs/components/flow-outline-editor.md +0 -0
  80. package/docs/components/forms-and-dialogs.md +0 -0
  81. package/docs/components/input-fields.md +0 -0
  82. package/docs/components/keymap.md +0 -0
  83. package/docs/components/markdown-and-outline.md +0 -0
  84. package/docs/components/menus.md +41 -0
  85. package/docs/components/notifications.md +0 -0
  86. package/docs/components/panels-and-desktops.md +0 -0
  87. package/docs/components/record-list-and-fact-table.md +0 -0
  88. package/docs/components/settings-view.md +0 -0
  89. package/docs/components/shell.md +0 -0
  90. package/docs/components/slide-out-panel.md +0 -0
  91. package/docs/components/tiles.md +25 -0
  92. package/docs/components/wizard.md +0 -0
  93. package/docs/concepts/building-and-packaging.md +0 -0
  94. package/docs/concepts/domain-neutrality.md +0 -0
  95. package/docs/concepts/host-port.md +0 -0
  96. package/docs/concepts/packages-and-entry-points.md +0 -0
  97. package/docs/concepts/peer-dependencies.md +0 -0
  98. package/docs/concepts/state-guard.md +0 -0
  99. package/docs/concepts/styling.md +68 -0
  100. package/docs/quickstart.md +0 -0
  101. package/editor.js +0 -0
  102. package/flow.js +0 -0
  103. package/host.js +0 -0
  104. package/package.json +1 -1
  105. package/src/canvas/canvas_adapter.js +0 -0
  106. package/src/canvas/edge_router.js +0 -0
  107. package/src/canvas/graph/connector_router.js +0 -0
  108. package/src/canvas/graph/history_service.js +0 -0
  109. package/src/canvas/graph/node_platform.js +0 -0
  110. package/src/canvas/index.js +0 -0
  111. package/src/canvas/layered_layout.js +0 -0
  112. package/src/charts/chart_types.js +3 -2
  113. package/src/charts/data_series_plot_window.js +0 -0
  114. package/src/charts/downsample.js +0 -0
  115. package/src/charts/plot_config.js +0 -0
  116. package/src/charts/plot_config_editor.js +8 -2
  117. package/src/charts/plotly_wrapper.js +0 -0
  118. package/src/core/event_bus.js +0 -0
  119. package/src/core/logging.js +0 -0
  120. package/src/core/settings.js +0 -0
  121. package/src/core/state_guard.js +0 -0
  122. package/src/core/state_guard_config.js +0 -0
  123. package/src/core/state_machine.js +0 -0
  124. package/src/editor/editor_pane.js +0 -0
  125. package/src/editor/monaco_editor_factory.js +0 -0
  126. package/src/editor/monaco_loader.js +0 -0
  127. package/src/editor/notebook_search.js +0 -0
  128. package/src/editor/notebook_tab_bar.js +26 -7
  129. package/src/editor/notebook_undo_manager.js +0 -0
  130. package/src/editor/split_pane_container.js +0 -0
  131. package/src/flow/canvas_editor/connections.js +0 -0
  132. package/src/flow/canvas_editor/editor.js +0 -0
  133. package/src/flow/canvas_editor/index.js +0 -0
  134. package/src/flow/canvas_editor/layout.js +0 -0
  135. package/src/flow/canvas_editor/strings.js +0 -0
  136. package/src/flow/kit/always_before.js +0 -0
  137. package/src/flow/kit/catalogue.js +0 -0
  138. package/src/flow/kit/chip_input.js +0 -0
  139. package/src/flow/kit/dom.js +0 -0
  140. package/src/flow/kit/findings.js +0 -0
  141. package/src/flow/kit/history.js +0 -0
  142. package/src/flow/kit/index.js +0 -0
  143. package/src/flow/kit/keys.js +0 -0
  144. package/src/flow/kit/logic_graph.js +0 -0
  145. package/src/flow/kit/references.js +0 -0
  146. package/src/flow/kit/settings_panel.js +0 -0
  147. package/src/flow/kit/settings_schema.js +0 -0
  148. package/src/flow/kit/step_picker.js +0 -0
  149. package/src/flow/kit/strings.js +0 -0
  150. package/src/flow/kit/value_picker.js +0 -0
  151. package/src/flow/kit/widgets.js +0 -0
  152. package/src/flow/lanes/editor.js +0 -0
  153. package/src/flow/lanes/index.js +0 -0
  154. package/src/flow/lanes/layout.js +0 -0
  155. package/src/flow/lanes/pipeline.js +0 -0
  156. package/src/flow/lanes/preview.js +0 -0
  157. package/src/flow/lanes/strings.js +0 -0
  158. package/src/flow/outline/editor.js +0 -0
  159. package/src/flow/outline/index.js +0 -0
  160. package/src/flow/outline/mapping.js +0 -0
  161. package/src/flow/outline/menu.js +0 -0
  162. package/src/flow/outline/operations.js +0 -0
  163. package/src/flow/outline/recognise.js +0 -0
  164. package/src/flow/outline/strings.js +0 -0
  165. package/src/help/help_modal.js +0 -0
  166. package/src/help/help_registry.js +0 -0
  167. package/src/host/external_links.js +0 -0
  168. package/src/host/file_picker.js +0 -0
  169. package/src/host/host.js +0 -0
  170. package/src/host/photino_host.js +0 -0
  171. package/src/host/photino_host.md +0 -0
  172. package/src/host/pywebview_host.js +0 -0
  173. package/src/tiles/chart_tiles.js +0 -0
  174. package/src/tiles/config_schema.js +0 -0
  175. package/src/tiles/figure_tile.js +0 -0
  176. package/src/tiles/layout_persistence.js +0 -0
  177. package/src/tiles/list_tiles.js +0 -0
  178. package/src/tiles/scope_picker.js +0 -0
  179. package/src/tiles/tile_base.js +67 -16
  180. package/src/tiles/tile_config_form.js +0 -0
  181. package/src/tiles/tile_grid.js +0 -0
  182. package/src/tiles/tile_registry.js +0 -0
  183. package/src/tiling/bottom_panel_tabs.js +0 -0
  184. package/src/tiling/command_palette.js +0 -0
  185. package/src/tiling/content_registry.js +0 -0
  186. package/src/tiling/desktops.js +0 -0
  187. package/src/tiling/entity_sources.js +0 -0
  188. package/src/tiling/keymap.js +0 -0
  189. package/src/tiling/kind_taxonomy.js +0 -0
  190. package/src/tiling/landing_table.js +0 -0
  191. package/src/tiling/loading_overlay.js +0 -0
  192. package/src/tiling/nav_panel.js +0 -0
  193. package/src/tiling/page_factory.js +0 -0
  194. package/src/tiling/panel_availability.js +0 -0
  195. package/src/tiling/panel_keys.js +0 -0
  196. package/src/tiling/shell.js +0 -0
  197. package/src/tiling/tab_strip.js +0 -0
  198. package/src/tiling/tile_breadcrumb.js +0 -0
  199. package/src/tiling/tile_renderer.js +0 -0
  200. package/src/tiling/tile_tab_menu.js +0 -0
  201. package/src/tiling/tile_tree.js +0 -0
  202. package/src/tiling/wm.js +0 -0
  203. package/src/tiling/zoom.js +0 -0
  204. package/src/ui/base/component_base.js +0 -0
  205. package/src/ui/base/controller_base.js +0 -0
  206. package/src/ui/base/page_base.js +0 -0
  207. package/src/ui/components/about_dialog.js +0 -0
  208. package/src/ui/components/action_dropdown.js +19 -6
  209. package/src/ui/components/alert_log.js +0 -0
  210. package/src/ui/components/alerts_pane.js +0 -0
  211. package/src/ui/components/attribute_list_editor.js +0 -0
  212. package/src/ui/components/autocomplete_field.js +0 -0
  213. package/src/ui/components/cell_editor_host.js +0 -0
  214. package/src/ui/components/cell_editors.js +0 -0
  215. package/src/ui/components/cell_grid.js +0 -0
  216. package/src/ui/components/cell_paste.js +0 -0
  217. package/src/ui/components/cell_selection.js +0 -0
  218. package/src/ui/components/choice_controls.js +0 -0
  219. package/src/ui/components/color_field.js +0 -0
  220. package/src/ui/components/color_list_field.js +0 -0
  221. package/src/ui/components/column_fit.js +0 -0
  222. package/src/ui/components/column_groups.js +0 -0
  223. package/src/ui/components/column_order.js +0 -0
  224. package/src/ui/components/computing_status_window.js +0 -0
  225. package/src/ui/components/confirm_dialog.js +0 -0
  226. package/src/ui/components/context_menu.js +20 -20
  227. package/src/ui/components/conversation_view.js +0 -0
  228. package/src/ui/components/crosstab.js +0 -0
  229. package/src/ui/components/data_table.js +45 -19
  230. package/src/ui/components/detail_header.js +0 -0
  231. package/src/ui/components/document_outline.js +0 -0
  232. package/src/ui/components/drag_reorder.js +0 -0
  233. package/src/ui/components/fact_table.js +0 -0
  234. package/src/ui/components/fill_handle.js +0 -0
  235. package/src/ui/components/gallery_picker.js +0 -0
  236. package/src/ui/components/header_actions.js +0 -0
  237. package/src/ui/components/inline_renamer.js +0 -0
  238. package/src/ui/components/job_progress.js +0 -0
  239. package/src/ui/components/managed_window.js +0 -0
  240. package/src/ui/components/menu_bar.js +0 -0
  241. package/src/ui/components/modal.js +0 -0
  242. package/src/ui/components/notification_history.js +0 -0
  243. package/src/ui/components/progress.js +0 -0
  244. package/src/ui/components/record_list.js +0 -0
  245. package/src/ui/components/row_activation.js +0 -0
  246. package/src/ui/components/section_stack.js +0 -0
  247. package/src/ui/components/series.js +0 -0
  248. package/src/ui/components/settings_view.js +0 -0
  249. package/src/ui/components/slide_out_panel.js +0 -0
  250. package/src/ui/components/slider_field.js +0 -0
  251. package/src/ui/components/sortable_list.js +0 -0
  252. package/src/ui/components/staged_edits.js +0 -0
  253. package/src/ui/components/staged_history.js +0 -0
  254. package/src/ui/components/table_filter_chips.js +0 -0
  255. package/src/ui/components/table_state_store.js +0 -0
  256. package/src/ui/components/table_structure.js +0 -0
  257. package/src/ui/components/table_values.js +0 -0
  258. package/src/ui/components/tabs.js +0 -0
  259. package/src/ui/components/tag_input.js +0 -0
  260. package/src/ui/components/toast.js +0 -0
  261. package/src/ui/components/toggle_field.js +0 -0
  262. package/src/ui/components/tree_view.js +0 -0
  263. package/src/ui/components/tsv.js +0 -0
  264. package/src/ui/components/window_taskbar.js +0 -0
  265. package/src/ui/components/wizard.js +0 -0
  266. package/src/ui/controllers/window_chrome_controller.js +0 -0
  267. package/src/ui/notification_center.js +0 -0
  268. package/src/ui/utils/auto_scrollbars.js +0 -0
  269. package/src/ui/utils/markdown.js +0 -0
  270. package/src/ui/utils/menu_viewport.js +81 -0
  271. package/src/ui/utils/native_context_menu.js +0 -0
  272. package/src/ui/utils/overlay_scrollbar.js +0 -0
  273. package/src/ui/utils/raf_resize_observer.js +0 -0
  274. package/src/ui/utils/scroll_lock.js +0 -0
  275. package/src/ui/utils/strip_scroll.js +0 -0
  276. package/src/ui/utils/tooltip_service.js +0 -0
  277. package/tiles.js +0 -0
  278. package/widgets.js +0 -0
  279. package/wm.js +0 -0
  280. package/dist/chunk-EIYNF4BD.js.map +0 -7
  281. package/dist/chunk-LWV23YVE.js.map +0 -7
  282. package/dist/chunk-UURZ37SD.js.map +0 -7
  283. package/dist/chunk-UWO43BZU.js.map +0 -7
package/dist/tokens.css CHANGED
@@ -90,6 +90,13 @@
90
90
  --accent-hover: #1177bb;
91
91
  --accent-bright: #007acc; /* --layout-accent value */
92
92
 
93
+ /* Every other accent colour is DERIVED from the three above, so a
94
+ consumer that sets them (on :root) rethemes the whole accent (BUG-0044).
95
+ The light accents mix --accent-bright toward white: a slider thumb, a
96
+ sortable list's drop line and add button, a focused filter input. */
97
+ --accent-light: color-mix(in srgb, var(--accent-bright) 70%, white); /* ≈ #4da2db, was #569cd6 */
98
+ --accent-lighter: color-mix(in srgb, var(--accent-bright) 55%, white); /* ≈ #73b6e3, was #6eb3e9 */
99
+
93
100
  /* ── Semantic colors ───────────────────────────────────────── */
94
101
  --color-success: #3fb950;
95
102
  --color-warning: #ff9800;
@@ -100,7 +107,9 @@
100
107
  /* ── Surface state overlays ────────────────────────────────── */
101
108
  --state-hover: rgba(255, 255, 255, 0.05);
102
109
  --state-active: rgba(255, 255, 255, 0.08);
103
- --state-selected: rgba(0, 122, 204, 0.15);
110
+ --state-selected: color-mix(in srgb, var(--accent-bright) 15%, transparent); /* rgba(0, 122, 204, 0.15) */
111
+ /* A DataTable row or cell that has just arrived flashes from this to transparent. */
112
+ --twm-dt-new-bg: color-mix(in srgb, var(--accent-bright) 22%, transparent); /* rgba(0, 122, 204, 0.22) */
104
113
 
105
114
  /* ── Overlay scrollbars (installOverlayScrollbar) ─────────── */
106
115
  --scrollbar-size: 6px;
@@ -114,7 +123,7 @@
114
123
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
115
124
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
116
125
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
117
- --shadow-glow: 0 0 2px rgba(0, 122, 204, 0.3);
126
+ --shadow-glow: 0 0 2px color-mix(in srgb, var(--accent-bright) 30%, transparent); /* rgba(0, 122, 204, 0.3) */
118
127
 
119
128
  /* ── Z-index layers ───────────────────────────────────────── */
120
129
  --z-base: 0;
package/dist/widgets.js CHANGED
@@ -17,16 +17,16 @@ import {
17
17
  import {
18
18
  TAB_LEVELS,
19
19
  createTabs
20
- } from "./chunk-HYJYYEPK.js";
20
+ } from "./chunk-REJ5HLIM.js";
21
21
  import {
22
22
  ActionDropdown,
23
23
  ComponentBase,
24
24
  SlideOutPanel
25
- } from "./chunk-RKNFBX5K.js";
25
+ } from "./chunk-MIW7D6WC.js";
26
26
  import {
27
27
  hideContextMenu,
28
28
  showContextMenu
29
- } from "./chunk-UWO43BZU.js";
29
+ } from "./chunk-F35XSQWA.js";
30
30
  import {
31
31
  ColorListField,
32
32
  SortableList,
@@ -35,7 +35,7 @@ import {
35
35
  openForm,
36
36
  openModal,
37
37
  setModalHost
38
- } from "./chunk-D3COLZZ2.js";
38
+ } from "./chunk-BE2PU3LL.js";
39
39
  import {
40
40
  ACTIONS,
41
41
  AutocompleteField,
@@ -82,7 +82,7 @@ import {
82
82
  resolvePaging,
83
83
  toTSV,
84
84
  tsvCell
85
- } from "./chunk-LWV23YVE.js";
85
+ } from "./chunk-NIJEJAZ7.js";
86
86
  import {
87
87
  ColorField,
88
88
  DEFAULT_WINDOW_STORAGE_KEY,
@@ -106,7 +106,7 @@ import {
106
106
  } from "./chunk-N7HC3ADV.js";
107
107
  import {
108
108
  DragReorder
109
- } from "./chunk-WVFGV5FT.js";
109
+ } from "./chunk-WUFLGETN.js";
110
110
  import "./chunk-JYWURG5T.js";
111
111
 
112
112
  // src/ui/base/controller_base.js
File without changes
package/dist/wm.js CHANGED
@@ -5,13 +5,13 @@ import {
5
5
  import {
6
6
  TAB_LEVELS,
7
7
  createTabs
8
- } from "./chunk-HYJYYEPK.js";
8
+ } from "./chunk-REJ5HLIM.js";
9
9
  import {
10
10
  showContextMenu
11
- } from "./chunk-UWO43BZU.js";
11
+ } from "./chunk-F35XSQWA.js";
12
12
  import {
13
13
  openForm
14
- } from "./chunk-D3COLZZ2.js";
14
+ } from "./chunk-BE2PU3LL.js";
15
15
  import {
16
16
  ManagedWindow,
17
17
  isRowActivation
@@ -19,9 +19,9 @@ import {
19
19
  import "./chunk-HNU6MM2B.js";
20
20
  import {
21
21
  NotebookTabBar
22
- } from "./chunk-UURZ37SD.js";
22
+ } from "./chunk-7U4IB65H.js";
23
23
  import "./chunk-N7HC3ADV.js";
24
- import "./chunk-WVFGV5FT.js";
24
+ import "./chunk-WUFLGETN.js";
25
25
  import "./chunk-JYWURG5T.js";
26
26
 
27
27
  // src/tiling/bottom_panel_tabs.js
package/dist/wm.js.map CHANGED
File without changes
package/docs/README.md CHANGED
File without changes
File without changes
@@ -4,6 +4,35 @@
4
4
 
5
5
  Plotly-backed charts: the wrapper, the chart types, subplot layouts, downsampling, the plot grid, the plot-config editor and the two plot windows. Plotly itself is not in the bundle; call `setPlotlySource()` with the path to your copy. The plot window's `streamEvents` option is described with the [other application-neutral options](../concepts/domain-neutrality.md#no-application-globals-the-gallery-picker-and-plot-window-events-0170).
6
6
 
7
+ ## Interpolation `'auto'` is a listed choice (0.17.9)
8
+
9
+ A subplot's `interpolation` is `'linear'`, `'step'`, `'cubic'` or `'auto'`.
10
+ `'auto'` draws straight segments between the points, exactly as `'linear'`
11
+ does (`buildTrace` gives both the Plotly line shape `linear`, as it always
12
+ has); it is the value embedders such as EcoSim save for their plots.
13
+ [`renderPlotConfigEditor`](#editing-a-plot-config-renderplotconfigeditor-0170)
14
+ offered only Linear, Step and Cubic spline, so a subplot saved with `'auto'`
15
+ opened with `auto (not found)` in **Interpolation**. The select now offers
16
+ **Auto**, **Linear**, **Step** and **Cubic spline**: a subplot saved with
17
+ `'auto'` opens with Auto chosen and keeps `'auto'` until you pick something
18
+ else, and picking Auto writes `'auto'`. A new subplot is still `'linear'`
19
+ (`makeDefaultSubplot`), and every value draws as before.
20
+
21
+ `tests/plot_config_editor.test.mjs` §11 pins it.
22
+
23
+ ## The plot config editor writes no stray "null" (0.17.9)
24
+
25
+ [`renderPlotConfigEditor`](#editing-a-plot-config-renderplotconfigeditor-0170)
26
+ drew a subplot's sections into one body and appended the sections a subplot
27
+ does not have as `null`, which `Element.append()` writes as the text `null`.
28
+ So every 2D subplot showed a `null` line between the Y axes and **Reference
29
+ lines** (where a 3D chart's **Z axis** goes), and an editor without
30
+ `seriesTransforms` showed another after **Shaded bands** (where **Derived
31
+ series** goes). The body now holds its sections and nothing else: a section
32
+ the subplot does not have is left out. Nothing else about the editor changed.
33
+
34
+ `tests/plot_config_editor.test.mjs` §10 pins it.
35
+
7
36
  ## A series transform knows its series, and takes a choice parameter (0.17.8)
8
37
 
9
38
  Two additions to [`seriesTransforms`](#derived-series-seriestransforms-0170).
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -4,6 +4,35 @@
4
4
 
5
5
  `createMenuBar` draws File / Edit / View menus from one declarative model, with pointer and keyboard behaviour and the WAI-ARIA menubar roles, and plugs into the shell. `ActionDropdown` draws a dropdown of action buttons from a trigger.
6
6
 
7
+ ## Context menus stay inside the window (0.17.9)
8
+
9
+ FlexDesk's own context menus: `showContextMenu(x, y, items, onAction)`, the
10
+ DataTable's right-click menu (its copy items and your `contextMenuItems`), and
11
+ `NotebookTabBar`'s tab menu. All three are placed the same way, however many
12
+ items they hold:
13
+
14
+ - **At most the window's height.** A menu is capped at the window's height
15
+ less 8px above and below. A longer menu scrolls inside (flexdesk.css gives
16
+ `.twm-context-menu` and `.nb-context-menu` `overflow-y: auto` and
17
+ `box-sizing: border-box`). Before, a menu had no cap: the DataTable's
18
+ opened above the window's top edge (a 101-item menu at y=-2153 in a 761px
19
+ window), and `showContextMenu`'s ran off the bottom. In both cases the items
20
+ past the edge could not be reached.
21
+ - **At the pointer, moved only to fit.** A menu opens with its top-left
22
+ corner at the pointer. When that does not fit, it moves left or up just
23
+ enough, and never past the window's top or left edge.
24
+ - **Every item can be reached from the keyboard.** The first enabled item has
25
+ focus when the menu opens. Up/Down (wrapping), Home and End move focus and
26
+ scroll the focused item into view inside the menu. Enter and Space choose,
27
+ and Escape closes. When the menu closes, focus goes back to where it was
28
+ (unless a click elsewhere has already moved it). The DataTable's menu and
29
+ the tab menu now do this too: before, only `showContextMenu` did.
30
+ - **Scrolling the menu does not close it.** `showContextMenu` still closes
31
+ when the page scrolls, and the DataTable's menu when anything outside it
32
+ scrolls.
33
+
34
+ Nothing changes in how you call them.
35
+
7
36
  ## A menu bar: `createMenuBar` (0.17.0)
8
37
 
9
38
  File / Edit / View menus from one declarative model, instead of hand-built
@@ -84,3 +113,15 @@ doubled rule. `setOptions` follows the same rules, and an option's
84
113
  `data-index` stays its index in `options`.
85
114
 
86
115
  `tests/action_dropdown_separators.test.mjs` drives it in jsdom.
116
+
117
+ ## Action dropdowns: positioning against the end edge (0.17.9)
118
+
119
+ `ActionDropdown.position(trigger, menu, { align })` places any menu against
120
+ any trigger: `position: fixed`, under the trigger when it fits there (else above it
121
+ when it fits there, else on the side with more room, scrolling inside), and kept 8px
122
+ inside the window. `align` says which trigger edge the menu lines up with
123
+ first: `'start'` (the default, and what it did before) its left edge, `'end'`
124
+ its right edge. Either flips to the other edge when the menu would leave the
125
+ window. A tile's ⋯ menu uses `'end'`
126
+ ([Dashboard tiles](tiles.md#the--menu-is-drawn-over-the-page-0179)).
127
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -13,6 +13,7 @@ Two different things in FlexDesk are called "tiles". `@flexdesk/wm` tiles the *w
13
13
  - [Figure tiles: one override, the draw is the base's (0.17.0)](#figure-tiles-one-override-the-draw-is-the-bases-0170)
14
14
  - [List and people tiles, and one scope for the board (0.16.1)](#list-and-people-tiles-and-one-scope-for-the-board-0161)
15
15
  - [A tile's settings as a form: `mountTileConfigForm` (0.17.0)](#a-tiles-settings-as-a-form-mounttileconfigform-0170)
16
+ - [The ⋯ menu is drawn over the page (0.17.9)](#the--menu-is-drawn-over-the-page-0179)
16
17
 
17
18
  ## Layouts are keyed by whatever you key them by
18
19
 
@@ -208,3 +209,27 @@ modal is open is ignored. It answers a function that unsubscribes and closes the
208
209
  slide-out; an open modal is left to the user, keeps its form and still saves on
209
210
  Save. A renderer's `commit` on a `readonly` field applies nothing and answers
210
211
  `{valid: false, error}`.
212
+
213
+ ## The ⋯ menu is drawn over the page (0.17.9)
214
+
215
+ A tile's **More actions** menu (`.tile-menu-dropdown`, the entries of
216
+ `menuItems()`) is no longer drawn inside the tile. While it is open it is
217
+ moved to `document.body` (or to the open modal's host, as `showContextMenu`
218
+ does) and placed with `ActionDropdown.position(button, menu, { align: 'end' })`:
219
+
220
+ - **Nothing clips it.** It is `position: fixed`, on `--z-over-windows`, so it
221
+ draws over neighbouring tiles, and over the managed window a grid sits in.
222
+ - **It stays in the window.** Its right edge lines up with the ⋯ button's
223
+ when there is room; otherwise its left edge does, clamped 8px inside the
224
+ window. It opens under the button when it fits there, else above it when it
225
+ fits there, else on the side with more room, scrolling inside.
226
+ - **It goes back when it closes.** Choosing an entry, a press outside it, or
227
+ the ⋯ button again closes it and puts it back in the tile's header, so
228
+ `tile.element.querySelector('.tile-menu-item')` finds the entries while it
229
+ is closed. `dispose()` closes an open menu first, so none is left on the
230
+ page.
231
+
232
+ Until 0.17.8 the menu was `position: absolute` inside the tile, so in a tile
233
+ narrower than about 220px its left part and its labels were cut off
234
+ (BUG-0043). `tests/tile_menu_unclipped.test.mjs` holds it.
235
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -45,3 +45,71 @@ its plain elements (headings, code, tables, lists).
45
45
  Icons are rendered by applying the `material-symbols-outlined` class. FlexDesk does
46
46
  not ship the font — supply it from Google Fonts or self-host. Without it, icons fall
47
47
  back to their text names and nothing breaks.
48
+
49
+ ## Retheming the accent (0.17.10)
50
+
51
+ The accent colours in `flexdesk.css` that were the literal `#007acc`
52
+ (`rgb(0, 122, 204)`), its tints, and the light accent `#569cd6` /
53
+ `#6eb3e9` are now derived from an accent token. Setting the tokens on `:root`
54
+ rethemes all of them:
55
+
56
+ ```css
57
+ :root {
58
+ --accent: #8a2be2;
59
+ --accent-hover: #9b4dea;
60
+ --accent-bright: #a64dff; /* selections, focus rings, tints, primary buttons, the slider thumb */
61
+ }
62
+ ```
63
+
64
+ `--accent` and `--accent-hover` stay literals. `--accent-bright` is the one
65
+ the rest is derived from, in `tokens.css`:
66
+
67
+ - `--state-selected`: `color-mix(in srgb, var(--accent-bright) 15%, transparent)`.
68
+ It was `rgba(0, 122, 204, 0.15)`, the same colour.
69
+ - `--shadow-glow`: `0 0 2px color-mix(in srgb, var(--accent-bright) 30%, transparent)`.
70
+ It was `0 0 2px rgba(0, 122, 204, 0.3)`, the same colour.
71
+ - `--twm-dt-new-bg` (new): `color-mix(in srgb, var(--accent-bright) 22%, transparent)`,
72
+ the colour a DataTable row or cell that has just arrived flashes from.
73
+ The stylesheet read it before, with an `rgba(0, 122, 204, 0.22)`
74
+ fallback, but nothing defined it.
75
+ - `--accent-light` (new): `color-mix(in srgb, var(--accent-bright) 70%, white)`,
76
+ about `#4da2db`. It replaces `#569cd6`.
77
+ - `--accent-lighter` (new): `color-mix(in srgb, var(--accent-bright) 55%, white)`,
78
+ about `#73b6e3`. It replaces `#6eb3e9`.
79
+
80
+ You can still set `--state-selected`, `--shadow-glow` or `--twm-dt-new-bg`
81
+ yourself. Set the derived tokens on `:root`, as `tokens.css` does: a custom
82
+ property that reads `var(--accent-bright)` is resolved where it is declared,
83
+ so an `--accent-bright` set on a lower element does not reach the tokens
84
+ derived from it on `:root`.
85
+
86
+ What changed in the stylesheet:
87
+
88
+ - **Tints.** The `rgba(0, 122, 204, a)` tints are now
89
+ `color-mix(in srgb, var(--accent-bright) a%, transparent)`, with the same
90
+ colour by default. They are the DataTable's selected rows and cells, the
91
+ filter chip when on, the autocomplete's namespace pill and active item,
92
+ `.add-widget-btn`, `.tile.resizing`, `.tile-ghost`, the focused leaf's inset
93
+ shadow, the document outline's active link, the canvas marquee and the
94
+ flow graph's port dots.
95
+ - **The light accent.** The SliderField thumb, the SortableList drop line,
96
+ add button and input focus, the DataTable filter inputs' focus border and
97
+ the notebook autocomplete's border read `--accent-light`. The active thumb
98
+ reads `--accent-lighter`. `#569cd6` cannot be mixed exactly from `#007acc`,
99
+ so these move to the nearest mix of `--accent-bright` with white: the thumb
100
+ goes from `#569cd6` to about `#4da2db`, and the active thumb from `#6eb3e9`
101
+ to about `#73b6e3`, a difference of about 1.5 to 1.7 ΔE (OKLab × 100).
102
+ - **No fallbacks.** `var(--accent-bright, #007acc)`, `var(--state-selected, …)`,
103
+ `var(--ea-accent, …)` and `var(--accent, …)` no longer carry fallbacks.
104
+ `tokens.css` defines all of them, so no computed colour changes, but
105
+ `flexdesk.css` now needs `tokens.css` (or your own definitions of these tokens).
106
+
107
+ Not part of the accent, and still literals: the autocomplete's type colours
108
+ (`stock` is `#569cd6` beside `#4ec9b0`, `#ce9178`, …), the notification
109
+ border `#4fc1ff`, and links (`#3794ff`).
110
+
111
+ Some accent blues in other shades are still literals, because no mix of an
112
+ accent token gives their colour exactly. They include the selected tile
113
+ (`#78b9ff`), the primary button's hover (`#1683c4`, `#1486cf`), the row
114
+ cursor and snap preview (`rgba(17, 119, 179, a)`), and some flow-lanes and
115
+ plot-window colours. To retheme them, override their rules.
File without changes
package/editor.js CHANGED
File without changes
package/flow.js CHANGED
File without changes
package/host.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flexdesk",
3
- "version": "0.17.8",
3
+ "version": "0.17.10",
4
4
  "description": "A tiling window manager and widget set for desktop-class web applications. Zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "repository": {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -61,7 +61,8 @@ const LINE_DASH_MAP = {
61
61
  };
62
62
 
63
63
  /**
64
- * Interpolation mapping (Chart.js to Plotly line shape)
64
+ * Interpolation mapping (Chart.js to Plotly line shape). 'auto' draws straight
65
+ * segments between the points, as 'linear' does.
65
66
  */
66
67
  const INTERPOLATION_MAP = {
67
68
  linear: 'linear',
@@ -81,7 +82,7 @@ const INTERPOLATION_MAP = {
81
82
  * @param {string} [options.color] - Series color (hex)
82
83
  * @param {number} [options.lineWidth] - Line width in pixels
83
84
  * @param {string} [options.lineStyle] - Line style: solid, dashed, dotted
84
- * @param {string} [options.interpolation] - Interpolation: linear, step, cubic
85
+ * @param {string} [options.interpolation] - Interpolation: linear, step, cubic, or auto (drawn as linear)
85
86
  * @param {string} [options.yAxisId] - Y-axis identifier (y, y2, y3, etc.)
86
87
  * @param {boolean} [options.showMarkers] - Show data point markers
87
88
  * @param {number} [options.seriesIndex] - Index for default color selection
File without changes
File without changes
File without changes
@@ -63,7 +63,10 @@ const LEGEND_POSITIONS = Object.freeze([
63
63
  { value: 'hidden', label: 'Hidden' }, { value: 'top', label: 'Top' }, { value: 'bottom', label: 'Bottom' },
64
64
  { value: 'left', label: 'Left' }, { value: 'right', label: 'Right' },
65
65
  ]);
66
+ // 'auto' is drawn as 'linear' (buildTrace); it is listed so a config saved with it
67
+ // shows it and keeps it.
66
68
  const INTERPOLATIONS = Object.freeze([
69
+ { value: 'auto', label: 'Auto' },
67
70
  { value: 'linear', label: 'Linear' }, { value: 'step', label: 'Step' }, { value: 'cubic', label: 'Cubic spline' },
68
71
  ]);
69
72
  const NAN_STRATEGIES = Object.freeze([
@@ -364,7 +367,10 @@ function renderPlotConfigEditor(container, config, options = {}) {
364
367
  let sources = null;
365
368
  const overlaySources = () => (sources ??= Promise.resolve().then(() => opts.overlaySources()));
366
369
 
367
- body.append(
370
+ // Element.append() writes a null child as the text "null": a section the
371
+ // subplot does not have (the z axis of a 2D chart, the transforms when
372
+ // there are none) is left out, not appended.
373
+ body.append(...[
368
374
  section('Subplot', field('Title', textInput(sp.displayName, (v) => { sp.displayName = v; notify(); },
369
375
  { placeholder: 'Untitled' }))),
370
376
  section('Display', ...displayFields(sp)),
@@ -374,7 +380,7 @@ function renderPlotConfigEditor(container, config, options = {}) {
374
380
  section('Reference lines', referenceLinesEditor(sp)),
375
381
  section('Shaded bands', shadedBandsEditor(sp)),
376
382
  transformsSection(sp),
377
- );
383
+ ].filter(Boolean));
378
384
  }
379
385
 
380
386
  function displayFields(sp) {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -24,6 +24,7 @@
24
24
 
25
25
  import { DragReorder } from '../ui/components/drag_reorder.js';
26
26
  import { revealInStrip, wheelStripSideways } from '../ui/utils/strip_scroll.js';
27
+ import { placeMenuInViewport, moveMenuFocus, focusMenuItem } from '../ui/utils/menu_viewport.js';
27
28
 
28
29
  /** The MIME type a dragged editor tab carries when the embedder names none. */
29
30
  export const DEFAULT_TAB_DRAG_MIME = 'application/x-flexdesk-tab';
@@ -64,6 +65,8 @@ export class NotebookTabBar {
64
65
 
65
66
  /** @type {HTMLElement|null} */
66
67
  #contextMenuEl = null;
68
+ /** BUG-0040. What had focus when the menu opened. @type {Element|null} */
69
+ #contextMenuReturnFocus = null;
67
70
 
68
71
  /** @type {Function|null} */
69
72
  #boundHideContextMenu = null;
@@ -417,6 +420,7 @@ export class NotebookTabBar {
417
420
 
418
421
  const menu = document.createElement('div');
419
422
  menu.className = 'nb-context-menu';
423
+ menu.setAttribute('role', 'menu');
420
424
 
421
425
  for (const item of cleaned) {
422
426
  if (item.separator) {
@@ -427,6 +431,8 @@ export class NotebookTabBar {
427
431
  }
428
432
 
429
433
  const btn = document.createElement('button');
434
+ btn.type = 'button';
435
+ btn.setAttribute('role', 'menuitem');
430
436
  btn.className = 'nb-context-menu__item';
431
437
  if (item.danger) btn.classList.add('nb-context-menu__item--danger');
432
438
  if (item.disabled) btn.classList.add('nb-context-menu__item--disabled');
@@ -445,15 +451,14 @@ export class NotebookTabBar {
445
451
  menu.appendChild(btn);
446
452
  }
447
453
 
454
+ this.#contextMenuReturnFocus = document.activeElement;
448
455
  document.body.appendChild(menu);
449
456
  this.#contextMenuEl = menu;
450
457
 
451
- // Position with viewport clamping
452
- const rect = menu.getBoundingClientRect();
453
- const left = Math.min(x, window.innerWidth - rect.width - 8);
454
- const top = Math.min(y, window.innerHeight - rect.height - 8);
455
- menu.style.left = `${Math.max(0, left)}px`;
456
- menu.style.top = `${Math.max(0, top)}px`;
458
+ // BUG-0040. Inside the window, at most its height, scrolling when
459
+ // longer; the keyboard starts on the first item it can use.
460
+ placeMenuInViewport(menu, x, y);
461
+ focusMenuItem(this.#contextMenuItems()[0]);
457
462
 
458
463
  // Animate in
459
464
  requestAnimationFrame(() => menu.classList.add('visible'));
@@ -468,15 +473,29 @@ export class NotebookTabBar {
468
473
 
469
474
  #hideContextMenu() {
470
475
  if (!this.#contextMenuEl) return;
476
+ const returnTo = this.#contextMenuReturnFocus;
477
+ const held = this.#contextMenuEl.contains(document.activeElement);
471
478
  this.#contextMenuEl.remove();
472
479
  this.#contextMenuEl = null;
480
+ this.#contextMenuReturnFocus = null;
473
481
  document.removeEventListener('click', this.#boundHideContextMenu, true);
474
482
  document.removeEventListener('contextmenu', this.#boundHideContextMenu, true);
475
483
  document.removeEventListener('keydown', this.#onKeyDown);
484
+ if (held && returnTo?.isConnected) returnTo.focus?.({ preventScroll: true });
485
+ }
486
+
487
+ /** BUG-0040. The menu's items the keyboard can land on. */
488
+ #contextMenuItems() {
489
+ return this.#contextMenuEl
490
+ ? [...this.#contextMenuEl.querySelectorAll('.nb-context-menu__item:not(.nb-context-menu__item--disabled)')]
491
+ : [];
476
492
  }
477
493
 
478
494
  #onKeyDown = (e) => {
479
- if (e.key === 'Escape') this.#hideContextMenu();
495
+ if (e.key === 'Escape') { this.#hideContextMenu(); return; }
496
+ // BUG-0040. Up/Down/Home/End move between the items and scroll the
497
+ // focused one into view; Enter and Space are the buttons' own.
498
+ moveMenuFocus(e, this.#contextMenuItems());
480
499
  };
481
500
 
482
501
  #handleContextMenuAction(action, filePath) {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes