flexdesk 0.17.17 → 0.17.18

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 (211) hide show
  1. package/CHANGELOG.md +17 -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 +20 -0
  9. package/css/flexdesk.css +20 -0
  10. package/css/reset.css +0 -0
  11. package/dist/canvas.js +0 -0
  12. package/dist/canvas.js.map +0 -0
  13. package/dist/chunk-3PHCPZHT.js +0 -0
  14. package/dist/chunk-3PHCPZHT.js.map +0 -0
  15. package/dist/chunk-FOOS3T5L.js +0 -0
  16. package/dist/chunk-FOOS3T5L.js.map +0 -0
  17. package/dist/chunk-GOQLR5WR.js +0 -0
  18. package/dist/chunk-GOQLR5WR.js.map +0 -0
  19. package/dist/{chunk-JKZLNKG6.js → chunk-HKPB6OFA.js} +90 -25
  20. package/dist/{chunk-JKZLNKG6.js.map → chunk-HKPB6OFA.js.map} +2 -2
  21. package/dist/chunk-HNU6MM2B.js +0 -0
  22. package/dist/chunk-HNU6MM2B.js.map +0 -0
  23. package/dist/chunk-JYWURG5T.js +0 -0
  24. package/dist/chunk-JYWURG5T.js.map +0 -0
  25. package/dist/chunk-N7HC3ADV.js +0 -0
  26. package/dist/chunk-N7HC3ADV.js.map +0 -0
  27. package/dist/editor.js.map +0 -0
  28. package/dist/flexdesk.css +20 -0
  29. package/dist/flow.js.map +0 -0
  30. package/dist/host.js +0 -0
  31. package/dist/host.js.map +0 -0
  32. package/dist/reset.css +0 -0
  33. package/dist/tile_registry-6WZPTUZV.js +0 -0
  34. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  35. package/dist/widgets.js +2 -1
  36. package/dist/widgets.js.map +2 -2
  37. package/dist/wm.js +1 -1
  38. package/docs/components/command-palette.md +0 -0
  39. package/docs/components/conversation.md +0 -0
  40. package/docs/components/data-table-grid.md +0 -0
  41. package/docs/components/data-table.md +0 -0
  42. package/docs/components/editor.md +0 -0
  43. package/docs/components/flow-canvas-editor.md +0 -0
  44. package/docs/components/flow-editors.md +0 -0
  45. package/docs/components/flow-lane-editor.md +0 -0
  46. package/docs/components/flow-outline-editor.md +0 -0
  47. package/docs/components/input-fields.md +0 -0
  48. package/docs/components/markdown-and-outline.md +0 -0
  49. package/docs/components/menus.md +38 -1
  50. package/docs/components/record-list-and-fact-table.md +0 -0
  51. package/docs/components/settings-view.md +0 -0
  52. package/docs/components/wizard.md +0 -0
  53. package/docs/concepts/building-and-packaging.md +0 -0
  54. package/docs/concepts/domain-neutrality.md +0 -0
  55. package/docs/concepts/host-port.md +0 -0
  56. package/docs/concepts/packages-and-entry-points.md +0 -0
  57. package/docs/concepts/peer-dependencies.md +0 -0
  58. package/docs/quickstart.md +0 -0
  59. package/editor.js +0 -0
  60. package/flow.js +0 -0
  61. package/host.js +0 -0
  62. package/package.json +1 -1
  63. package/src/canvas/canvas_adapter.js +0 -0
  64. package/src/canvas/edge_router.js +0 -0
  65. package/src/canvas/graph/connector_router.js +0 -0
  66. package/src/canvas/graph/history_service.js +0 -0
  67. package/src/canvas/graph/node_platform.js +0 -0
  68. package/src/canvas/index.js +0 -0
  69. package/src/canvas/layered_layout.js +0 -0
  70. package/src/charts/data_series_plot_window.js +0 -0
  71. package/src/charts/downsample.js +0 -0
  72. package/src/charts/plot_config.js +0 -0
  73. package/src/charts/plotly_wrapper.js +0 -0
  74. package/src/core/event_bus.js +0 -0
  75. package/src/core/logging.js +0 -0
  76. package/src/core/settings.js +0 -0
  77. package/src/core/state_guard.js +0 -0
  78. package/src/core/state_machine.js +0 -0
  79. package/src/editor/editor_pane.js +0 -0
  80. package/src/editor/monaco_editor_factory.js +0 -0
  81. package/src/editor/monaco_loader.js +0 -0
  82. package/src/editor/notebook_search.js +0 -0
  83. package/src/editor/notebook_undo_manager.js +0 -0
  84. package/src/editor/split_pane_container.js +0 -0
  85. package/src/flow/canvas_editor/connections.js +0 -0
  86. package/src/flow/canvas_editor/editor.js +0 -0
  87. package/src/flow/canvas_editor/index.js +0 -0
  88. package/src/flow/canvas_editor/layout.js +0 -0
  89. package/src/flow/canvas_editor/strings.js +0 -0
  90. package/src/flow/kit/always_before.js +0 -0
  91. package/src/flow/kit/catalogue.js +0 -0
  92. package/src/flow/kit/chip_input.js +0 -0
  93. package/src/flow/kit/dom.js +0 -0
  94. package/src/flow/kit/findings.js +0 -0
  95. package/src/flow/kit/history.js +0 -0
  96. package/src/flow/kit/index.js +0 -0
  97. package/src/flow/kit/keys.js +0 -0
  98. package/src/flow/kit/logic_graph.js +0 -0
  99. package/src/flow/kit/references.js +0 -0
  100. package/src/flow/kit/settings_panel.js +0 -0
  101. package/src/flow/kit/settings_schema.js +0 -0
  102. package/src/flow/kit/step_picker.js +0 -0
  103. package/src/flow/kit/strings.js +0 -0
  104. package/src/flow/kit/value_picker.js +0 -0
  105. package/src/flow/kit/widgets.js +0 -0
  106. package/src/flow/lanes/editor.js +0 -0
  107. package/src/flow/lanes/index.js +0 -0
  108. package/src/flow/lanes/layout.js +0 -0
  109. package/src/flow/lanes/pipeline.js +0 -0
  110. package/src/flow/lanes/preview.js +0 -0
  111. package/src/flow/lanes/strings.js +0 -0
  112. package/src/flow/outline/editor.js +0 -0
  113. package/src/flow/outline/index.js +0 -0
  114. package/src/flow/outline/mapping.js +0 -0
  115. package/src/flow/outline/menu.js +0 -0
  116. package/src/flow/outline/operations.js +0 -0
  117. package/src/flow/outline/recognise.js +0 -0
  118. package/src/flow/outline/strings.js +0 -0
  119. package/src/help/help_modal.js +0 -0
  120. package/src/help/help_registry.js +0 -0
  121. package/src/host/external_links.js +0 -0
  122. package/src/host/file_picker.js +0 -0
  123. package/src/host/host.js +0 -0
  124. package/src/host/photino_host.js +0 -0
  125. package/src/host/photino_host.md +0 -0
  126. package/src/host/pywebview_host.js +0 -0
  127. package/src/tiles/chart_tiles.js +0 -0
  128. package/src/tiles/config_schema.js +0 -0
  129. package/src/tiles/figure_tile.js +0 -0
  130. package/src/tiles/layout_persistence.js +0 -0
  131. package/src/tiles/list_tiles.js +0 -0
  132. package/src/tiles/scope_picker.js +0 -0
  133. package/src/tiles/tile_config_form.js +0 -0
  134. package/src/tiles/tile_registry.js +0 -0
  135. package/src/tiling/bottom_panel_tabs.js +0 -0
  136. package/src/tiling/command_palette.js +0 -0
  137. package/src/tiling/content_registry.js +0 -0
  138. package/src/tiling/entity_sources.js +0 -0
  139. package/src/tiling/landing_table.js +0 -0
  140. package/src/tiling/loading_overlay.js +0 -0
  141. package/src/tiling/nav_panel.js +0 -0
  142. package/src/tiling/page_factory.js +0 -0
  143. package/src/tiling/panel_availability.js +0 -0
  144. package/src/tiling/panel_keys.js +0 -0
  145. package/src/tiling/tab_strip.js +0 -0
  146. package/src/tiling/tile_renderer.js +0 -0
  147. package/src/tiling/tile_tab_menu.js +0 -0
  148. package/src/tiling/zoom.js +0 -0
  149. package/src/ui/base/component_base.js +0 -0
  150. package/src/ui/base/controller_base.js +0 -0
  151. package/src/ui/base/page_base.js +0 -0
  152. package/src/ui/components/about_dialog.js +0 -0
  153. package/src/ui/components/alert_log.js +0 -0
  154. package/src/ui/components/alerts_pane.js +0 -0
  155. package/src/ui/components/attribute_list_editor.js +0 -0
  156. package/src/ui/components/autocomplete_field.js +0 -0
  157. package/src/ui/components/cell_editor_host.js +0 -0
  158. package/src/ui/components/cell_editors.js +0 -0
  159. package/src/ui/components/cell_grid.js +0 -0
  160. package/src/ui/components/cell_paste.js +0 -0
  161. package/src/ui/components/cell_selection.js +0 -0
  162. package/src/ui/components/choice_controls.js +0 -0
  163. package/src/ui/components/color_field.js +0 -0
  164. package/src/ui/components/color_list_field.js +0 -0
  165. package/src/ui/components/column_fit.js +0 -0
  166. package/src/ui/components/column_groups.js +0 -0
  167. package/src/ui/components/column_order.js +0 -0
  168. package/src/ui/components/conversation_view.js +0 -0
  169. package/src/ui/components/crosstab.js +0 -0
  170. package/src/ui/components/detail_header.js +0 -0
  171. package/src/ui/components/document_outline.js +0 -0
  172. package/src/ui/components/drag_reorder.js +0 -0
  173. package/src/ui/components/fact_table.js +0 -0
  174. package/src/ui/components/fill_handle.js +0 -0
  175. package/src/ui/components/gallery_picker.js +0 -0
  176. package/src/ui/components/header_actions.js +0 -0
  177. package/src/ui/components/inline_renamer.js +0 -0
  178. package/src/ui/components/job_progress.js +0 -0
  179. package/src/ui/components/menu_bar.js +101 -24
  180. package/src/ui/components/progress.js +0 -0
  181. package/src/ui/components/record_list.js +0 -0
  182. package/src/ui/components/row_activation.js +0 -0
  183. package/src/ui/components/section_stack.js +0 -0
  184. package/src/ui/components/series.js +0 -0
  185. package/src/ui/components/settings_view.js +0 -0
  186. package/src/ui/components/slide_out_panel.js +0 -0
  187. package/src/ui/components/slider_field.js +0 -0
  188. package/src/ui/components/sortable_list.js +0 -0
  189. package/src/ui/components/staged_edits.js +0 -0
  190. package/src/ui/components/staged_history.js +0 -0
  191. package/src/ui/components/table_filter_chips.js +0 -0
  192. package/src/ui/components/table_state_store.js +0 -0
  193. package/src/ui/components/table_structure.js +0 -0
  194. package/src/ui/components/table_values.js +0 -0
  195. package/src/ui/components/tabs.js +0 -0
  196. package/src/ui/components/tag_input.js +0 -0
  197. package/src/ui/components/toast.js +0 -0
  198. package/src/ui/components/toggle_field.js +0 -0
  199. package/src/ui/components/tsv.js +0 -0
  200. package/src/ui/components/window_taskbar.js +0 -0
  201. package/src/ui/controllers/window_chrome_controller.js +4 -1
  202. package/src/ui/utils/auto_scrollbars.js +0 -0
  203. package/src/ui/utils/markdown.js +0 -0
  204. package/src/ui/utils/native_context_menu.js +0 -0
  205. package/src/ui/utils/overlay_scrollbar.js +0 -0
  206. package/src/ui/utils/raf_resize_observer.js +0 -0
  207. package/src/ui/utils/scroll_lock.js +0 -0
  208. package/src/ui/utils/strip_scroll.js +0 -0
  209. package/src/ui/utils/tooltip_service.js +0 -0
  210. package/tiles.js +0 -0
  211. package/wm.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.18 (2026-10-27)
4
+
5
+ A patch release. One additive menu bar option; one entry changes what
6
+ embedders see (listed under "Changed behaviour").
7
+
8
+ ### Added
9
+
10
+ - [A hamburger instead of the bar: `style: 'hamburger'`](docs/components/menus.md#a-hamburger-instead-of-the-bar-style-hamburger-01718): `createMenuBar` (and `createShell`'s `menuBar`) can draw the menus as one icon button whose menu flies out each menu's items. Same model, `onAction`, `setEnabled` / `setChecked` and `commands()`; `open(menuId)` opens it with that menu flown out. `bar.setStyle('bar' | 'hamburger')` switches at run time and `bar.style` reads it; `icon` sets the glyph (`'menu'`) (STORY-0133).
11
+
12
+ ### Changed behaviour
13
+
14
+ - `WindowChromeController` never starts a window drag from a press inside a `.twm-menubar`: a hamburger in the top bar drops its menus inside the bar, and a press on a menu's padding or separator dragged the window (STORY-0133).
15
+
16
+ ### Removed or renamed exports
17
+
18
+ None. New: `MenuBar#setStyle`, `MenuBar#style`, the `style` and `icon` options, the `.twm-menubar--hamburger` and `.twm-menubar__title--icon` classes.
19
+
3
20
  ## 0.17.17 (2026-10-27)
4
21
 
5
22
  A patch release. One additive taxonomy option and notification copying; one
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
File without changes
File without changes
package/canvas.js CHANGED
File without changes
package/charts.js CHANGED
File without changes
package/core.js CHANGED
File without changes
package/css/base.css CHANGED
@@ -7033,6 +7033,26 @@ button.twm-about-dialog__btn--close:focus {
7033
7033
  margin: var(--space-xs) var(--space-md);
7034
7034
  background: var(--surface-3);
7035
7035
  }
7036
+ /* The hamburger (STORY-0133, `style: 'hamburger'`): one icon button in place
7037
+ * of the titles, the size of the top bar's other icon buttons
7038
+ * (.twm-panel-toggle-btn: a 22px box, an --font-size-xl glyph). Its menu
7039
+ * lists the menus, each flying out its items. */
7040
+ .twm-menubar--hamburger {
7041
+ align-items: center;
7042
+ }
7043
+ .twm-menubar__title--icon {
7044
+ display: inline-flex;
7045
+ align-items: center;
7046
+ justify-content: center;
7047
+ width: 22px;
7048
+ height: 22px;
7049
+ padding: 0;
7050
+ color: var(--text-secondary);
7051
+ }
7052
+ .twm-menubar__title--icon .material-symbols-outlined {
7053
+ font-size: var(--font-size-xl);
7054
+ line-height: 1;
7055
+ }
7036
7056
  /* ══ end MENU BAR ══ */
7037
7057
 
7038
7058
  /* ══ TOGGLE ══════════════════════════════════════════════════════════
package/css/flexdesk.css CHANGED
@@ -10695,6 +10695,26 @@ button.twm-alerts__ref:hover { text-decoration: underline; }
10695
10695
  margin: var(--space-xs) var(--space-md);
10696
10696
  background: var(--surface-3);
10697
10697
  }
10698
+ /* The hamburger (STORY-0133, `style: 'hamburger'`): one icon button in place
10699
+ * of the titles, the size of the top bar's other icon buttons
10700
+ * (.twm-panel-toggle-btn: a 22px box, an --font-size-xl glyph). Its menu
10701
+ * lists the menus, each flying out its items. */
10702
+ .twm-menubar--hamburger {
10703
+ align-items: center;
10704
+ }
10705
+ .twm-menubar__title--icon {
10706
+ display: inline-flex;
10707
+ align-items: center;
10708
+ justify-content: center;
10709
+ width: 22px;
10710
+ height: 22px;
10711
+ padding: 0;
10712
+ color: var(--text-secondary);
10713
+ }
10714
+ .twm-menubar__title--icon .material-symbols-outlined {
10715
+ font-size: var(--font-size-xl);
10716
+ line-height: 1;
10717
+ }
10698
10718
  /* ══ end MENU BAR ══ */
10699
10719
 
10700
10720
  /* ══ TOGGLE ══════════════════════════════════════════════════════════
package/css/reset.css CHANGED
File without changes
package/dist/canvas.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1389,6 +1389,8 @@ function installHelpShortcut({ target = document } = {}) {
1389
1389
  var SEL_TITLE = ".twm-menubar__title";
1390
1390
  var SEL_ITEM = ".twm-menubar__item";
1391
1391
  var SEL_MENU = ".twm-menubar__menu";
1392
+ var STYLES = ["bar", "hamburger"];
1393
+ var HAMBURGER = "twm-menubar:hamburger";
1392
1394
  function createMenuBar(el, opts) {
1393
1395
  return new MenuBar(el, opts);
1394
1396
  }
@@ -1400,16 +1402,22 @@ var MenuBar = class {
1400
1402
  * @param {Function} [opts.onAction] `(id, { item, checked }) => void`
1401
1403
  * @param {string} [opts.label] the bar's accessible name ('Menu')
1402
1404
  * @param {string} [opts.emptyLabel] the disabled row an empty submenu shows ('Empty')
1405
+ * @param {string} [opts.style] 'bar' (a title per menu, the default) or 'hamburger' (one button)
1406
+ * @param {string} [opts.icon] the hamburger's Material Symbols icon ('menu')
1403
1407
  */
1404
- constructor(el, { menus, onAction = null, label = "Menu", emptyLabel = "Empty" } = {}) {
1408
+ constructor(el, { menus, onAction = null, label = "Menu", emptyLabel = "Empty", style = "bar", icon = "menu" } = {}) {
1405
1409
  if (!el || typeof el.appendChild !== "function") {
1406
1410
  throw new TypeError("createMenuBar: `el` must be an element");
1407
1411
  }
1408
1412
  _validateMenus(menus);
1413
+ _validateStyle(style);
1409
1414
  this.el = el;
1410
1415
  this.menus = menus;
1411
1416
  this._onAction = typeof onAction === "function" ? onAction : null;
1412
1417
  this._emptyLabel = emptyLabel;
1418
+ this._label = label;
1419
+ this._icon = icon;
1420
+ this._style = style;
1413
1421
  this._doc = el.ownerDocument;
1414
1422
  this._disabled = /* @__PURE__ */ new Map();
1415
1423
  this._checked = /* @__PURE__ */ new Map();
@@ -1420,26 +1428,10 @@ var MenuBar = class {
1420
1428
  this._active = false;
1421
1429
  this._returnTo = null;
1422
1430
  this._altArmed = false;
1423
- el.innerHTML = "";
1424
1431
  el.classList.add("twm-menubar");
1425
1432
  el.setAttribute("role", "menubar");
1426
1433
  el.setAttribute("aria-label", label);
1427
- this._titles = menus.map((m, i) => {
1428
- const entry = this._doc.createElement("div");
1429
- entry.className = "twm-menubar__entry";
1430
- entry.setAttribute("role", "none");
1431
- const btn = this._doc.createElement("button");
1432
- btn.type = "button";
1433
- btn.className = "twm-menubar__title";
1434
- btn.setAttribute("role", "menuitem");
1435
- btn.setAttribute("aria-haspopup", "menu");
1436
- btn.setAttribute("aria-expanded", "false");
1437
- btn.tabIndex = i === 0 ? 0 : -1;
1438
- btn.textContent = m.label;
1439
- entry.appendChild(btn);
1440
- el.appendChild(entry);
1441
- return btn;
1442
- });
1434
+ this._renderTitles();
1443
1435
  this._h = {
1444
1436
  mousedown: (e) => this._onMouseDown(e),
1445
1437
  click: (e) => this._onClick(e),
@@ -1473,12 +1465,37 @@ var MenuBar = class {
1473
1465
  isOpen() {
1474
1466
  return this._openIdx >= 0;
1475
1467
  }
1476
- /** Open the menu with this id (focus on its title, or on its first item). */
1468
+ /** Open the menu with this id (focus on its title, or on its first item).
1469
+ * A hamburger opens with that menu flown out (focus on its row, or on
1470
+ * the menu's first item). */
1477
1471
  open(menuId, { focusItem = false } = {}) {
1478
1472
  const i = this.menus.findIndex((m) => m.id === menuId);
1479
1473
  if (i < 0) return;
1480
1474
  this._enter();
1481
- this._open(i, focusItem ? "first" : null);
1475
+ if (this._style !== "hamburger") {
1476
+ this._open(i, focusItem ? "first" : null);
1477
+ return;
1478
+ }
1479
+ this._open(0, null);
1480
+ const row = this._itemsIn(this._stack[0].menu).find((b) => this._models.get(b)?.id === `${HAMBURGER}:${menuId}`);
1481
+ if (!row) return;
1482
+ row.focus({ preventScroll: true });
1483
+ this._openSub(row, focusItem ? "first" : null);
1484
+ }
1485
+ /** 'bar' or 'hamburger'. */
1486
+ get style() {
1487
+ return this._style;
1488
+ }
1489
+ /** Draw the menus as a bar or as one hamburger button. Whatever is open
1490
+ * closes; the model and every setEnabled / setChecked stay. */
1491
+ setStyle(style) {
1492
+ _validateStyle(style);
1493
+ if (style === this._style) return;
1494
+ const hadFocus = this.el.contains(this._doc.activeElement);
1495
+ this._deactivate();
1496
+ this._style = style;
1497
+ this._renderTitles();
1498
+ if (hadFocus) this._focusTitle(0);
1482
1499
  }
1483
1500
  /** Close every open menu. Focus stays in the bar if it was there. */
1484
1501
  close() {
@@ -1546,7 +1563,7 @@ var MenuBar = class {
1546
1563
  this._doc.removeEventListener("mousedown", this._h.docMousedown, true);
1547
1564
  this._doc.defaultView?.removeEventListener("blur", this._h.winBlur);
1548
1565
  this.el.innerHTML = "";
1549
- this.el.classList.remove("twm-menubar");
1566
+ this.el.classList.remove("twm-menubar", "twm-menubar--hamburger");
1550
1567
  this.el.removeAttribute("role");
1551
1568
  this.el.removeAttribute("aria-label");
1552
1569
  }
@@ -1616,6 +1633,48 @@ var MenuBar = class {
1616
1633
  btn.setAttribute("aria-checked", this._isChecked(item) ? "true" : "false");
1617
1634
  }
1618
1635
  }
1636
+ // ── titles ────────────────────────────────────────────────────────
1637
+ /** The titles for the current style. `_top` is what they open: the
1638
+ * menus themselves, or the hamburger's one menu that lists them. */
1639
+ _renderTitles() {
1640
+ const d = this._doc;
1641
+ const burger = this._style === "hamburger";
1642
+ this.el.innerHTML = "";
1643
+ this.el.classList.toggle("twm-menubar--hamburger", burger);
1644
+ this._top = burger ? [{ id: HAMBURGER, label: this._label, items: this.menus.map((m) => ({
1645
+ id: `${HAMBURGER}:${m.id}`,
1646
+ label: m.label,
1647
+ submenu: m.items
1648
+ })) }] : this.menus;
1649
+ this._titles = this._top.map((m, i) => {
1650
+ const entry = d.createElement("div");
1651
+ entry.className = "twm-menubar__entry";
1652
+ entry.setAttribute("role", "none");
1653
+ const btn = d.createElement("button");
1654
+ btn.type = "button";
1655
+ btn.className = "twm-menubar__title";
1656
+ btn.setAttribute("role", "menuitem");
1657
+ btn.setAttribute("aria-haspopup", "menu");
1658
+ btn.setAttribute("aria-expanded", "false");
1659
+ btn.tabIndex = i === 0 ? 0 : -1;
1660
+ if (burger) {
1661
+ btn.classList.add("twm-menubar__title--icon", "twm-has-tooltip");
1662
+ btn.setAttribute("aria-label", m.label);
1663
+ btn.dataset.tooltip = m.label;
1664
+ btn.dataset.tooltipPlacement = "bottom";
1665
+ const icon = d.createElement("span");
1666
+ icon.className = "material-symbols-outlined";
1667
+ icon.setAttribute("aria-hidden", "true");
1668
+ icon.textContent = this._icon;
1669
+ btn.appendChild(icon);
1670
+ } else {
1671
+ btn.textContent = m.label;
1672
+ }
1673
+ entry.appendChild(btn);
1674
+ this.el.appendChild(entry);
1675
+ return btn;
1676
+ });
1677
+ }
1619
1678
  // ── open / close ──────────────────────────────────────────────────
1620
1679
  _setRoving(i) {
1621
1680
  this._titles.forEach((t, j) => {
@@ -1652,7 +1711,7 @@ var MenuBar = class {
1652
1711
  i = (i % n + n) % n;
1653
1712
  this._focusTitle(i);
1654
1713
  this._closeAll();
1655
- const m = this.menus[i];
1714
+ const m = this._top[i];
1656
1715
  const title = this._titles[i];
1657
1716
  const menu = this._buildMenu(m.items, m.label);
1658
1717
  title.parentElement.appendChild(menu);
@@ -1875,6 +1934,7 @@ var MenuBar = class {
1875
1934
  _titleKey(key, i) {
1876
1935
  const n = this._titles.length;
1877
1936
  const open = this._openIdx >= 0;
1937
+ if (n === 1 && (key === "ArrowRight" || key === "ArrowLeft" || key === "Home" || key === "End")) return true;
1878
1938
  switch (key) {
1879
1939
  case "ArrowRight":
1880
1940
  open ? this._open(i + 1, null) : this._focusTitle((i + 1) % n);
@@ -1934,11 +1994,11 @@ var MenuBar = class {
1934
1994
  return true;
1935
1995
  case "ArrowRight":
1936
1996
  if (item?.submenu != null && !this._isDisabled(item)) this._openSub(btn, "first");
1937
- else this._open(this._openIdx + 1, "first");
1997
+ else if (this._titles.length > 1) this._open(this._openIdx + 1, "first");
1938
1998
  return true;
1939
1999
  case "ArrowLeft":
1940
2000
  if (level > 0) this._closeFrom(level);
1941
- else this._open(this._openIdx - 1, "first");
2001
+ else if (this._titles.length > 1) this._open(this._openIdx - 1, "first");
1942
2002
  return true;
1943
2003
  case "Enter":
1944
2004
  case " ":
@@ -1991,6 +2051,11 @@ function _kind(item) {
1991
2051
  if (typeof item.checked === "boolean") return "menuitemcheckbox";
1992
2052
  return "menuitem";
1993
2053
  }
2054
+ function _validateStyle(style) {
2055
+ if (!STYLES.includes(style)) {
2056
+ throw new TypeError(`createMenuBar: \`style\` must be ${STYLES.map((s) => `'${s}'`).join(" or ")}`);
2057
+ }
2058
+ }
1994
2059
  function _validateMenus(menus) {
1995
2060
  if (!Array.isArray(menus) || !menus.length) {
1996
2061
  throw new TypeError("createMenuBar: `menus` must be a non-empty array");
@@ -2038,4 +2103,4 @@ export {
2038
2103
  createMenuBar,
2039
2104
  MenuBar
2040
2105
  };
2041
- //# sourceMappingURL=chunk-JKZLNKG6.js.map
2106
+ //# sourceMappingURL=chunk-HKPB6OFA.js.map