flexdesk 0.17.18 → 0.18.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 (118) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +1 -0
  3. package/css/flexdesk.css +7544 -5916
  4. package/css/reset.css +1 -1
  5. package/css/tokens.css +23 -1
  6. package/dist/charts.js +10 -6
  7. package/dist/charts.js.map +1 -1
  8. package/dist/chunk-5W4EEKSK.js +778 -0
  9. package/dist/chunk-5W4EEKSK.js.map +7 -0
  10. package/dist/chunk-DNJ3N4T4.js +82 -0
  11. package/dist/chunk-DNJ3N4T4.js.map +7 -0
  12. package/dist/{chunk-REJ5HLIM.js → chunk-HYJYYEPK.js} +2 -2
  13. package/dist/{chunk-7U4IB65H.js → chunk-LLBJ2SJH.js} +5 -3
  14. package/dist/{chunk-7U4IB65H.js.map → chunk-LLBJ2SJH.js.map} +1 -1
  15. package/dist/{chunk-7OL6F2AM.js → chunk-P74F6I6P.js} +6 -4
  16. package/dist/{chunk-7OL6F2AM.js.map → chunk-P74F6I6P.js.map} +1 -1
  17. package/dist/chunk-PAI2ZUWV.js +260 -0
  18. package/dist/chunk-PAI2ZUWV.js.map +7 -0
  19. package/dist/chunk-Q7BALEPX.js +527 -0
  20. package/dist/chunk-Q7BALEPX.js.map +7 -0
  21. package/dist/chunk-QXAOTGCC.js +40 -0
  22. package/dist/chunk-QXAOTGCC.js.map +7 -0
  23. package/dist/{chunk-XJNADRGR.js → chunk-RKVYIXDC.js} +664 -91
  24. package/dist/chunk-RKVYIXDC.js.map +7 -0
  25. package/dist/{chunk-2Z2ENHR3.js → chunk-U5GKJUOC.js} +3 -3
  26. package/dist/{chunk-2Z2ENHR3.js.map → chunk-U5GKJUOC.js.map} +1 -1
  27. package/dist/chunk-UKP22RUG.js +219 -0
  28. package/dist/chunk-UKP22RUG.js.map +7 -0
  29. package/dist/chunk-VLOAI3HS.js +43 -0
  30. package/dist/chunk-VLOAI3HS.js.map +7 -0
  31. package/dist/{chunk-WUFLGETN.js → chunk-WVFGV5FT.js} +2 -39
  32. package/dist/{chunk-WUFLGETN.js.map → chunk-WVFGV5FT.js.map} +3 -3
  33. package/dist/{chunk-PGZ4EHSE.js → chunk-ZL3VKINP.js} +41 -390
  34. package/dist/chunk-ZL3VKINP.js.map +7 -0
  35. package/dist/editor.js +3 -2
  36. package/dist/editor.js.map +1 -1
  37. package/dist/flexdesk.css +7544 -5916
  38. package/dist/flow.js +29 -97
  39. package/dist/flow.js.map +3 -3
  40. package/dist/git.js +1356 -0
  41. package/dist/git.js.map +7 -0
  42. package/dist/reset.css +1 -1
  43. package/dist/tiles.js +20 -15
  44. package/dist/tiles.js.map +2 -2
  45. package/dist/tokens.css +23 -1
  46. package/dist/widgets.js +3967 -1188
  47. package/dist/widgets.js.map +4 -4
  48. package/dist/wm.js +120 -32
  49. package/dist/wm.js.map +2 -2
  50. package/docs/README.md +9 -4
  51. package/docs/best-practices.md +2 -2
  52. package/docs/components/chat-shell.md +198 -0
  53. package/docs/components/conversation.md +10 -0
  54. package/docs/components/filter-builder.md +246 -0
  55. package/docs/components/forms-and-dialogs.md +22 -0
  56. package/docs/components/git.md +355 -0
  57. package/docs/components/input-fields.md +167 -2
  58. package/docs/components/keymap.md +8 -0
  59. package/docs/components/menus.md +82 -2
  60. package/docs/components/panels-and-desktops.md +16 -5
  61. package/docs/components/shell.md +104 -1
  62. package/docs/components/workspace-picker.md +149 -0
  63. package/docs/concepts/building-and-packaging.md +2 -2
  64. package/docs/concepts/packages-and-entry-points.md +14 -13
  65. package/docs/concepts/state-guard.md +3 -3
  66. package/docs/quickstart.md +1 -1
  67. package/git.js +13 -0
  68. package/package.json +6 -1
  69. package/src/flow/kit/dom.js +28 -119
  70. package/src/flow/kit/step_picker.js +1 -1
  71. package/src/flow/kit/value_picker.js +1 -1
  72. package/src/flow/outline/menu.js +1 -1
  73. package/src/git/diff_viewer.js +212 -0
  74. package/src/git/diff_window.js +51 -0
  75. package/src/git/git_graph.js +401 -0
  76. package/src/git/git_ops.js +61 -0
  77. package/src/git/git_panel.js +755 -0
  78. package/src/git/index.js +9 -0
  79. package/src/git/line_diff.js +202 -0
  80. package/src/tiles/tile_base.js +5 -4
  81. package/src/tiling/desktops.js +10 -8
  82. package/src/tiling/keymap.js +6 -5
  83. package/src/tiling/kind_taxonomy.js +15 -2
  84. package/src/tiling/shell.js +124 -17
  85. package/src/tiling/tile_renderer.js +2 -3
  86. package/src/ui/components/action_dropdown.js +4 -78
  87. package/src/ui/components/anchored_layer.js +255 -0
  88. package/src/ui/components/chat_shell.js +920 -0
  89. package/src/ui/components/chat_state_machine.js +223 -0
  90. package/src/ui/components/choice_controls.js +45 -2
  91. package/src/ui/components/color_field.js +3 -2
  92. package/src/ui/components/color_list_field.js +3 -2
  93. package/src/ui/components/combobox.js +422 -0
  94. package/src/ui/components/conversation_view.js +17 -2
  95. package/src/ui/components/data_table.js +2 -2
  96. package/src/ui/components/filter_builder.js +766 -0
  97. package/src/ui/components/filter_model.js +614 -0
  98. package/src/ui/components/managed_window.js +24 -47
  99. package/src/ui/components/modal.js +79 -109
  100. package/src/ui/components/option_list.js +160 -0
  101. package/src/ui/components/popover.js +94 -0
  102. package/src/ui/components/recent_items.js +169 -0
  103. package/src/ui/components/select.js +322 -0
  104. package/src/ui/components/tag_input.js +77 -8
  105. package/src/ui/components/workspace_picker.js +1155 -0
  106. package/src/ui/utils/fire_event.js +17 -0
  107. package/src/ui/utils/focusable.js +25 -0
  108. package/src/ui/utils/modal_host.js +27 -0
  109. package/widgets.js +12 -2
  110. package/css/base.css +0 -10547
  111. package/css/overrides.css +0 -2596
  112. package/dist/chunk-7JI7HHSY.js +0 -107
  113. package/dist/chunk-7JI7HHSY.js.map +0 -7
  114. package/dist/chunk-MIW7D6WC.js +0 -526
  115. package/dist/chunk-MIW7D6WC.js.map +0 -7
  116. package/dist/chunk-PGZ4EHSE.js.map +0 -7
  117. package/dist/chunk-XJNADRGR.js.map +0 -7
  118. /package/dist/{chunk-REJ5HLIM.js.map → chunk-HYJYYEPK.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/ui/components/progress.js", "../src/ui/components/job_progress.js", "../src/ui/components/confirm_dialog.js", "../src/ui/components/toast.js"],
4
+ "sourcesContent": ["/**\n * Determinate progress: a bar, a keyed list of bars, and a row of phases.\n * Location: ui/components/progress.js\n *\n * Three primitives for long-running jobs, each a class that owns its own DOM\n * and changes it IN PLACE \u2014 a caller that reports progress twenty times a\n * second gets the same elements back every time, so a row it is hovering, a\n * tooltip anchored to it and a CSS transition on the fill all survive.\n *\n * ProgressBar value/max or a 0..1 fraction, indeterminate, a label, a\n * percent and a count readout, elapsed time, a cancel button,\n * and a final state (done / error / cancelled).\n * ProgressList keyed rows `{ key, name, completed, total?, state }`;\n * `setItems` reconciles by key. A row without `total` is\n * drawn against the largest item in the list.\n * StepProgress ordered phases, each done / active / pending / error, the\n * active one optionally reading \"pass n of m\".\n *\n * Nothing here knows what is being computed: names, labels and the stats line\n * are the caller's text, always set with `textContent`. State lives on the\n * instances; the DOM carries only classes and ARIA.\n */\n\n/** The states a ProgressBar can end in, besides `running`. */\nexport const PROGRESS_STATES = Object.freeze(['running', 'done', 'error', 'cancelled']);\n\n/** The states a ProgressList row can be in. */\nexport const PROGRESS_ITEM_STATES = Object.freeze(['pending', 'running', 'done', 'failed']);\n\n/** The states a StepProgress phase can be in. */\nexport const STEP_STATES = Object.freeze(['pending', 'active', 'done', 'error']);\n\nconst clamp01 = (x) => (x < 0 ? 0 : x > 1 ? 1 : x);\nconst isNum = (x) => typeof x === 'number' && Number.isFinite(x);\n\n/** `m:ss`, or `h:mm:ss` from an hour on. */\nexport function formatElapsed(ms) {\n const s = Math.max(0, Math.floor((ms || 0) / 1000));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = String(s % 60).padStart(2, '0');\n return h ? `${h}:${String(m).padStart(2, '0')}:${ss}` : `${m}:${ss}`;\n}\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined) n.textContent = text;\n return n;\n}\n\n/** Set text only when it changed, so an unchanged readout is not a mutation. */\nfunction setText(node, text) {\n const t = text == null ? '' : String(text);\n if (node.textContent !== t) node.textContent = t;\n}\n\nfunction setWidth(node, fraction) {\n const w = `${(clamp01(fraction) * 100).toFixed(2).replace(/\\.?0+$/, '')}%`;\n if (node.style.width !== w) node.style.width = w;\n}\n\n// \u2500\u2500\u2500 ProgressBar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * @typedef {Object} ProgressBarOptions\n * @property {number} [value=0] - A count when `max` is given, else a 0..1 fraction.\n * @property {number|null} [max=null] - The count `value` runs to.\n * @property {boolean} [indeterminate=false] - Busy, with no known end.\n * @property {string} [label=''] - Text before the readout.\n * @property {boolean} [showPercent=true] - \"42%\".\n * @property {boolean|null} [showCount=null] - \"21 / 50\"; defaults to on when `max` is given.\n * @property {boolean} [showElapsed=false] - A running \"m:ss\" from construction until a final state.\n * @property {Function|null} [onCancel=null] - Shows a Cancel button; called once when clicked.\n * @property {string} [cancelLabel='Cancel']\n * @property {Function} [now=Date.now] - The clock, for the elapsed readout.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressBar {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressBarOptions} [options]\n */\n constructor(host, options = {}) {\n const {\n value = 0, max = null, indeterminate = false, label = '',\n showPercent = true, showCount = null, showElapsed = false,\n onCancel = null, cancelLabel = 'Cancel', now = Date.now, className = '',\n } = options;\n this._value = isNum(value) ? value : 0;\n this._max = isNum(max) && max > 0 ? max : null;\n this._indeterminate = !!indeterminate;\n this._label = label || '';\n this._showPercent = showPercent !== false;\n this._showCount = showCount;\n this._showElapsed = !!showElapsed;\n this._state = 'running';\n this._now = typeof now === 'function' ? now : Date.now;\n this._started = this._now();\n this._stopped = null;\n this._timer = null;\n this._onCancel = typeof onCancel === 'function' ? onCancel : null;\n\n const root = el('div', `twm-progress${className ? ` ${className}` : ''}`);\n const head = el('div', 'twm-progress__head');\n this._labelEl = el('span', 'twm-progress__label');\n this._readoutEl = el('span', 'twm-progress__readout');\n head.append(this._labelEl, this._readoutEl);\n if (this._showElapsed) {\n this._elapsedEl = el('span', 'twm-progress__elapsed');\n head.appendChild(this._elapsedEl);\n this._startTimer();\n } else {\n this._elapsedEl = null;\n }\n if (this._onCancel) {\n const btn = el('button', 'twm-progress__cancel', cancelLabel);\n btn.type = 'button';\n btn.addEventListener('click', () => {\n if (btn.disabled || this._state !== 'running') return;\n btn.disabled = true;\n this._onCancel();\n });\n this._cancelBtn = btn;\n head.appendChild(btn);\n } else {\n this._cancelBtn = null;\n }\n this._track = el('div', 'twm-progress__track');\n this._track.setAttribute('role', 'progressbar');\n this._fill = el('div', 'twm-progress__fill');\n this._track.appendChild(this._fill);\n root.append(head, this._track);\n this.element = root;\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** The bar's fraction 0..1, or null while indeterminate. */\n get fraction() {\n if (this._indeterminate) return null;\n return clamp01(this._max ? this._value / this._max : this._value);\n }\n\n /** `running`, `done`, `error` or `cancelled`. */\n get state() { return this._state; }\n\n /** Milliseconds since construction, frozen at the final state. */\n get elapsed() { return (this._stopped ?? this._now()) - this._started; }\n\n /**\n * Change the bar in place. A number is the new value (a count with `max`,\n * else a fraction); an object may carry `value`, `max`, `label` and\n * `indeterminate`. Ignored once the bar is in a final state.\n */\n update(next) {\n if (this._state !== 'running') return this;\n const o = isNum(next) ? { value: next } : (next || {});\n if ('max' in o) this._max = isNum(o.max) && o.max > 0 ? o.max : null;\n if (isNum(o.value)) { this._value = o.value; if (!('indeterminate' in o)) this._indeterminate = false; }\n if ('indeterminate' in o) this._indeterminate = !!o.indeterminate;\n if ('label' in o) this._label = o.label || '';\n this._draw();\n return this;\n }\n\n /**\n * Put the bar in a final state (`done`, `error`, `cancelled`) or back to\n * `running`. `done` fills it. A final state stops the elapsed clock and\n * disables Cancel; `running` restarts the clock (still counting from\n * construction) and enables Cancel again. `label` replaces the label when\n * given.\n */\n setState(state, { label } = {}) {\n if (!PROGRESS_STATES.includes(state)) throw new Error(`ProgressBar: unknown state \"${state}\"`);\n this._state = state;\n if (label !== undefined) this._label = label || '';\n if (state === 'done') { this._indeterminate = false; this._value = this._max ?? 1; }\n if (state === 'running') {\n this._stopped = null;\n if (this._showElapsed) this._startTimer();\n } else {\n this._stopped = this._now();\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n }\n if (this._cancelBtn) this._cancelBtn.disabled = state !== 'running';\n this._draw();\n this._drawElapsed();\n return this;\n }\n\n /** Tick the elapsed readout once a second, unless it already ticks. */\n _startTimer() {\n if (!this._timer) this._timer = setInterval(() => this._drawElapsed(), 1000);\n }\n\n /** Stop the elapsed clock and detach. */\n dispose() {\n this._showElapsed = false;\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n this.element.remove();\n }\n\n _draw() {\n const root = this.element;\n for (const s of PROGRESS_STATES) {\n root.classList.toggle(`twm-progress--${s}`, this._state === s);\n }\n root.classList.toggle('twm-progress--indeterminate', this._indeterminate);\n setText(this._labelEl, this._label);\n const f = this.fraction;\n const parts = [];\n if (f !== null) {\n if (this._showPercent) parts.push(`${Math.floor(f * 100)}%`);\n const count = this._showCount ?? !!this._max;\n if (count && this._max) parts.push(`${fmtCount(this._value)} / ${fmtCount(this._max)}`);\n }\n setText(this._readoutEl, parts.join(' \u00B7 '));\n if (f === null) {\n if (this._fill.style.width) this._fill.style.width = '';\n this._track.removeAttribute('aria-valuenow');\n } else {\n setWidth(this._fill, f);\n this._track.setAttribute('aria-valuenow', String(Math.round(f * 100)));\n }\n this._track.setAttribute('aria-valuemin', '0');\n this._track.setAttribute('aria-valuemax', '100');\n if (this._label) this._track.setAttribute('aria-label', this._label);\n this._drawElapsed();\n }\n\n _drawElapsed() {\n if (this._elapsedEl) setText(this._elapsedEl, formatElapsed(this.elapsed));\n }\n}\n\nfunction fmtCount(n) {\n return Number.isInteger(n) ? String(n) : String(Math.round(n * 100) / 100);\n}\n\n// \u2500\u2500\u2500 ProgressList \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * @typedef {Object} ProgressItem\n * @property {string|number} key - Identity across `setItems` calls.\n * @property {string} [name] - Shown as the row's label; defaults to the key.\n * @property {number} [completed=0]\n * @property {number} [total] - Absent: the row is drawn against the largest item.\n * @property {'pending'|'running'|'done'|'failed'} [state='pending']\n * @property {string} [detail] - Extra text after the count.\n */\n\n/**\n * @typedef {Object} ProgressListOptions\n * @property {ProgressItem[]} [items=[]]\n * @property {boolean|Function} [stats=true] - The line under the rows: `true`\n * for the default summary, `false` for none, or `(items) => string`.\n * @property {boolean} [pulse=true] - Running rows pulse.\n * @property {string} [emptyText=''] - Shown when there are no items.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressList {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressListOptions} [options]\n */\n constructor(host, options = {}) {\n const { items = [], stats = true, pulse = true, emptyText = '', className = '' } = options;\n this._stats = stats;\n this._emptyText = emptyText;\n /** @type {Map<string, {item: ProgressItem, row: HTMLElement, name: HTMLElement, fill: HTMLElement, count: HTMLElement, state: HTMLElement}>} */\n this._rows = new Map();\n this._items = [];\n const root = el('div', `twm-progress-list${pulse ? ' twm-progress-list--pulse' : ''}${className ? ` ${className}` : ''}`);\n this._listEl = el('div', 'twm-progress-list__rows');\n this._listEl.setAttribute('role', 'list');\n this._emptyEl = el('div', 'twm-progress-list__empty');\n this._statsEl = el('div', 'twm-progress-list__stats');\n root.append(this._listEl, this._emptyEl, this._statsEl);\n this.element = root;\n this.setItems(items);\n if (host) host.appendChild(root);\n }\n\n /** The items last given, in order. */\n get items() { return this._items.slice(); }\n\n /**\n * Reconcile the rows with `items` by key: a known key keeps its row and\n * has its text, width and state changed in place; a new key gets a row; a\n * key that is gone loses its row. Rows follow the order given, and a row\n * already in its place is not moved.\n */\n setItems(items) {\n const list = Array.isArray(items) ? items : [];\n const seen = new Set();\n this._items = [];\n for (const it of list) {\n if (!it || it.key == null) continue;\n const k = String(it.key);\n if (seen.has(k)) continue;\n seen.add(k);\n this._items.push(it);\n }\n for (const [k, r] of this._rows) {\n if (!seen.has(k)) { r.row.remove(); this._rows.delete(k); }\n }\n const scale = this._items.reduce((m, it) => {\n const d = isNum(it.total) && it.total > 0 ? it.total : (isNum(it.completed) ? it.completed : 0);\n return d > m ? d : m;\n }, 0);\n let prev = null;\n for (const it of this._items) {\n const k = String(it.key);\n let r = this._rows.get(k);\n if (!r) { r = this._makeRow(); this._rows.set(k, r); }\n this._drawRow(r, it, scale);\n const want = prev ? prev.nextSibling : this._listEl.firstChild;\n if (want !== r.row) this._listEl.insertBefore(r.row, want);\n prev = r.row;\n }\n this._emptyEl.hidden = this._items.length > 0 || !this._emptyText;\n setText(this._emptyEl, this._emptyText);\n const line = this._statsLine();\n this._statsEl.hidden = !line;\n setText(this._statsEl, line);\n return this;\n }\n\n /** The row element for `key`, or null. */\n rowFor(key) { return this._rows.get(String(key))?.row ?? null; }\n\n dispose() { this.element.remove(); this._rows.clear(); }\n\n _makeRow() {\n const row = el('div', 'twm-progress-list__row');\n row.setAttribute('role', 'listitem');\n const name = el('span', 'twm-progress-list__name');\n const track = el('div', 'twm-progress-list__track');\n const fill = el('div', 'twm-progress-list__fill');\n track.appendChild(fill);\n const count = el('span', 'twm-progress-list__count');\n const state = el('span', 'twm-progress-list__state');\n row.append(state, name, track, count);\n return { row, name, fill, count, state };\n }\n\n _drawRow(r, it, scale) {\n const state = PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending';\n for (const s of PROGRESS_ITEM_STATES) {\n r.row.classList.toggle(`twm-progress-list__row--${s}`, s === state);\n }\n const done = isNum(it.completed) ? it.completed : 0;\n const hasTotal = isNum(it.total) && it.total > 0;\n const denom = hasTotal ? it.total : scale;\n setWidth(r.fill, denom > 0 ? done / denom : 0);\n setText(r.name, it.name ?? String(it.key));\n const count = hasTotal ? `${fmtCount(done)} / ${fmtCount(it.total)}` : fmtCount(done);\n setText(r.count, it.detail ? `${count} \u00B7 ${it.detail}` : count);\n if (r.state.title !== state) r.state.title = state;\n }\n\n _statsLine() {\n if (this._stats === false) return '';\n if (typeof this._stats === 'function') return String(this._stats(this.items) ?? '');\n if (!this._items.length) return '';\n const n = { done: 0, running: 0, failed: 0, pending: 0 };\n let completed = 0;\n for (const it of this._items) {\n n[PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending'] += 1;\n if (isNum(it.completed)) completed += it.completed;\n }\n const parts = [`${n.done} / ${this._items.length} done`];\n if (n.running) parts.push(`${n.running} running`);\n if (n.failed) parts.push(`${n.failed} failed`);\n if (n.pending) parts.push(`${n.pending} pending`);\n parts.push(`${fmtCount(completed)} completed`);\n return parts.join(' \u00B7 ');\n }\n}\n\n// \u2500\u2500\u2500 StepProgress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * @typedef {Object} StepDef\n * @property {string} [key] - How `setStep` names it; defaults to its index.\n * @property {string} label\n */\n\nexport class StepProgress {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {{ steps?: Array<StepDef|string>, className?: string }} [options]\n */\n constructor(host, options = {}) {\n const { steps = [], className = '' } = options;\n const root = el('ol', `twm-steps${className ? ` ${className}` : ''}`);\n this.element = root;\n this._steps = steps.map((s, i) => {\n const def = typeof s === 'string' ? { label: s } : (s || {});\n const li = el('li', 'twm-steps__step');\n const marker = el('span', 'twm-steps__marker');\n const label = el('span', 'twm-steps__label', def.label ?? '');\n const pass = el('span', 'twm-steps__pass');\n pass.hidden = true;\n li.append(marker, label, pass);\n root.appendChild(li);\n return { key: def.key != null ? String(def.key) : String(i), label: def.label ?? '', state: 'pending', pass: null, li, passEl: pass };\n });\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** `[{ key, label, state, pass }]`, in order. */\n get steps() {\n return this._steps.map(({ key, label, state, pass }) => ({ key, label, state, pass }));\n }\n\n /** The index of the active phase, or -1. */\n get activeIndex() { return this._steps.findIndex((s) => s.state === 'active'); }\n\n /**\n * Make one phase active: every phase before it is done, every phase after\n * it pending. `pass` and `passes` read \"pass n of m\" on it.\n * @param {string|number} which - A key, or an index.\n * @param {{ pass?: number, passes?: number }} [opts]\n */\n setStep(which, { pass, passes } = {}) {\n const i = this._index(which);\n this._steps.forEach((s, j) => {\n s.state = j < i ? 'done' : j === i ? 'active' : 'pending';\n s.pass = j === i && isNum(pass) ? { n: pass, of: isNum(passes) ? passes : null } : null;\n });\n this._draw();\n return this;\n }\n\n /** Mark a phase (the active one by default) as failed; phases after it stay pending. */\n fail(which) {\n const i = which === undefined ? this.activeIndex : this._index(which);\n if (i < 0) return this;\n this._steps.forEach((s, j) => {\n if (j < i) s.state = 'done';\n else if (j === i) s.state = 'error';\n else s.state = 'pending';\n if (j !== i) s.pass = null;\n });\n this._draw();\n return this;\n }\n\n /** Every phase done. */\n complete() {\n for (const s of this._steps) { s.state = 'done'; s.pass = null; }\n this._draw();\n return this;\n }\n\n dispose() { this.element.remove(); }\n\n _index(which) {\n const i = typeof which === 'number'\n ? which\n : this._steps.findIndex((s) => s.key === String(which));\n if (!Number.isInteger(i) || i < 0 || i >= this._steps.length) {\n throw new Error(`StepProgress: no step \"${which}\"`);\n }\n return i;\n }\n\n _draw() {\n for (const s of this._steps) {\n for (const st of STEP_STATES) s.li.classList.toggle(`twm-steps__step--${st}`, s.state === st);\n if (s.state === 'active') s.li.setAttribute('aria-current', 'step');\n else s.li.removeAttribute('aria-current');\n const text = s.pass ? (s.pass.of ? `pass ${s.pass.n} of ${s.pass.of}` : `pass ${s.pass.n}`) : '';\n s.passEl.hidden = !text;\n setText(s.passEl, text);\n }\n }\n}\n", "/**\n * The progress block both job dialogs share \u2014 `showRunProgressDialog` and\n * `showComputingWindow` \u2014 so a bar and a row of phases behave the same in\n * either. Internal: not in the `widgets` barrel.\n */\n\nimport { ProgressBar, StepProgress } from './progress.js';\n\n/**\n * Mount the optional phases and bar into `parent`, phases first.\n *\n * @param {HTMLElement} parent\n * @param {{ progress?: boolean|Object, steps?: Array, spinner?: HTMLElement|null }} options\n * `progress`: `true`, or ProgressBar options (its `onCancel` is ignored: the\n * dialog owns cancelling). `steps`: StepProgress steps. `spinner`: hidden\n * while a bar is shown. Both are fixed at mount: `setProgress` throws\n * without `progress` and `setStep` without `steps`, so the window is sized\n * for what it holds from the start.\n */\nexport function mountJobProgress(parent, { progress = null, steps = null, spinner = null } = {}) {\n const stepper = Array.isArray(steps) && steps.length\n ? new StepProgress(parent, { steps, className: 'twm-job-progress__steps' })\n : null;\n let bar = null;\n if (progress) {\n const { onCancel: _ignored, ...rest } = typeof progress === 'object' ? progress : {};\n bar = new ProgressBar(parent, { ...rest, className: 'twm-job-progress__bar' });\n if (spinner) spinner.hidden = true;\n }\n\n return {\n get bar() { return bar; },\n get steps() { return stepper; },\n /** `bar.update(next)`. */\n setProgress(next) {\n if (!bar) throw new Error('setProgress: this dialog was opened without `progress`');\n bar.update(next);\n },\n /** `steps.setStep(which, opts)`. */\n setStep(which, opts) {\n if (!stepper) throw new Error('setStep: this dialog was opened without `steps`');\n stepper.setStep(which, opts);\n },\n /** Put the bar and the phases in their final state. */\n finish(status) {\n if (status === 'done') { bar?.setState('done'); stepper?.complete(); }\n else if (status === 'error') { bar?.setState('error'); stepper?.fail(); }\n else bar?.setState('cancelled');\n },\n };\n}\n", "/**\n * Confirm Dialog Component\n * Location: ui/components/confirm_dialog.js\n *\n * Thin delegator over the canonical modal helpers in\n * `ecoagent/ui/modal.js`. Every dialog signature here is preserved so\n * the 10+ call sites across notebook/data/results/ai pages keep\n * working unchanged; under the hood, all four standard dialogs now\n * flow through `openConfirm` / `openForm` / `openModal` so they\n * inherit the TUI styling (`\u25B8 TITLE` strip, accent-blue primary\n * action, square frame, Tab focus trap).\n *\n * The one custom case is `showRunProgressDialog`, which exposes an\n * imperative `update / setProgress / setStep / complete / cancelled /\n * close` API and a `result` promise, and so\n * stays as a direct `ManagedWindow` build \u2014 but it still benefits\n * from the focus trap + chrome by virtue of `modal: true`.\n */\n\nimport { ManagedWindow } from './managed_window.js';\nimport { mountJobProgress } from './job_progress.js';\nimport {\n openConfirm, openForm, openModal,\n} from './modal.js';\n\n// Counter \u2014 used only by showRunProgressDialog which still builds its\n// own ManagedWindow. The migrated helpers don't need it.\nlet dialogIdCounter = 0;\n\n/**\n * Show a confirmation dialog. Delegates to `openConfirm`.\n * @param {Object} options\n * @param {string} options.title\n * @param {string} options.message\n * @param {string} [options.icon='warning']\n * @param {string} [options.okLabel='OK']\n * @param {string} [options.cancelLabel='Cancel']\n * @param {string} [options.okVariant='primary'] - 'primary' or 'danger'\n * @returns {Promise<boolean>}\n */\nexport async function showConfirmDialog(options = {}) {\n const {\n title = 'Confirm',\n message = 'Are you sure?',\n icon = 'warning',\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n okVariant = 'primary',\n } = options;\n return openConfirm({\n title,\n message,\n icon,\n confirmLabel: okLabel,\n cancelLabel,\n danger: okVariant === 'danger',\n });\n}\n\n/**\n * Show a delete-confirmation dialog. Always danger-styled.\n * @returns {Promise<boolean>}\n */\nexport async function showDeleteConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'item',\n additionalMessage = '',\n } = options;\n // `openConfirm` renders the message as text, so a user-named item\n // (`<b>x</b>`, an unclosed `<`) is shown exactly as it was typed.\n let message = `Delete ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n if (additionalMessage) message += `\\n\\n${additionalMessage}`;\n return openConfirm({\n title: `Delete ${capitalize(itemType)}`,\n message,\n icon: 'delete',\n confirmLabel: 'Delete',\n cancelLabel: 'Cancel',\n danger: true,\n });\n}\n\n/**\n * Show a close-confirmation dialog.\n * @returns {Promise<boolean>}\n */\nexport async function showCloseConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'tab',\n } = options;\n let message = `Close ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n return openConfirm({\n title: `Close ${capitalize(itemType)}`,\n message,\n icon: 'close',\n confirmLabel: 'Close',\n cancelLabel: 'Cancel',\n });\n}\n\n/**\n * Show a dialog with multiple action buttons. Delegates to `openModal`\n * so each action maps to a button in the canonical footer.\n * @returns {Promise<string|null>}\n */\nexport async function showChoiceDialog(options = {}) {\n const {\n title = 'Choose',\n message = '',\n icon = 'warning',\n actions = [],\n } = options;\n const content = document.createElement('div');\n content.className = 'twm-confirm-dialog__body';\n content.innerHTML = `\n <span class=\"twm-confirm-dialog__icon material-symbols-outlined\">${escapeHtml(icon)}</span>\n <div class=\"twm-confirm-dialog__message\">${escapeHtml(message)}</div>\n `;\n return openModal({\n title,\n icon,\n content,\n width: 480,\n height: 220,\n actions: actions.map((a) => ({\n label: a.label,\n value: a.value,\n primary: a.variant === 'primary',\n danger: a.variant === 'danger',\n })),\n });\n}\n\n/**\n * Show a dialog with a dropdown select + OK/Cancel. Delegates to\n * `openForm` with a single select field.\n * @returns {Promise<string|null>}\n */\nexport async function showSelectDialog(options = {}) {\n const {\n title = 'Select',\n message = '',\n items = [],\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n } = options;\n const fields = [];\n if (message) {\n fields.push({ section: message });\n }\n fields.push({\n name: '_choice',\n label: 'Choice',\n type: 'select',\n default: items[0]?.value || '',\n options: items.map((i) => ({ value: i.value, label: i.label })),\n });\n // NB: cancelLabel is currently hardcoded as \"Cancel\" on openForm.\n // openConfirm has cancelLabel; if a caller really needs custom\n // cancel text on openForm, we'd extend openForm there. The\n // explicit no-op suppresses the unused-arg lint.\n void cancelLabel;\n const data = await openForm({\n title,\n submitLabel: okLabel,\n fields,\n });\n if (!data) return null;\n return data._choice;\n}\n\n\n// \u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction escapeHtml(str) {\n if (!str) return '';\n return String(str)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction capitalize(str) {\n if (!str) return '';\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n\n// \u2500\u2500\u2500 showRunProgressDialog (custom build) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// This one exposes an imperative API (`update`, `setProgress`, `setStep`,\n// `complete`, `cancelled`, `close`) that the openModal/openForm/openConfirm\n// helpers don't model \u2014 they're one-shot promise-returning. Keep the direct\n// ManagedWindow build, but it still gets the TUI chrome + focus trap for free\n// via `modal: true`.\n\n/**\n * @typedef {Object} RunProgressResult\n * @property {'done'|'error'|'cancelled'} status\n * @property {string} message\n */\n\n/**\n * Show a run progress dialog with a spinner (or a bar), live message\n * updates, optional phases, and a final status.\n *\n * `progress` (`true` or ProgressBar options) shows a determinate bar in place\n * of the spinner; `steps` (StepProgress steps) shows the phases above it.\n * Both are fixed when the dialog opens: `setProgress` throws if it was opened\n * without `progress`, and `setStep` if it was opened without `steps`.\n * `result` settles once, with the final state: `complete({ok})` gives `done`\n * or `error`, `cancelled()` gives `cancelled`, and so does closing the dialog\n * while it runs (by its \u00D7, Escape or `close()`). Closing never calls\n * `onCancel`: only the Stop button does.\n *\n * @param {Object} [options]\n * @param {string} [options.title='Running Pipeline']\n * @param {string} [options.message='Starting\u2026']\n * @param {Function} [options.onCancel] - Shows a Stop button.\n * @param {boolean|Object} [options.progress] - A ProgressBar, `true` or its options.\n * @param {Array} [options.steps] - StepProgress steps.\n * @returns {{ update(msg: string): void, setProgress(next: number|Object): void,\n * setStep(which: string|number, opts?: {pass?: number, passes?: number}): void,\n * complete(result: {ok: boolean, message: string}): void, cancelled(msg?: string): void,\n * close(): void, result: Promise<RunProgressResult> }}\n */\nexport function showRunProgressDialog(options = {}) {\n const {\n title = 'Running Pipeline',\n message = 'Starting\u2026',\n onCancel,\n progress = null,\n steps = null,\n } = options;\n\n const dialogId = `run-progress-${++dialogIdCounter}`;\n let finished = false;\n let settle;\n const result = new Promise((resolve) => { settle = resolve; });\n\n const contentEl = document.createElement('div');\n contentEl.className = 'twm-confirm-dialog__content run-progress';\n\n const bodyEl = document.createElement('div');\n bodyEl.className = 'twm-run-progress__body';\n const spinnerEl = document.createElement('div');\n spinnerEl.className = 'twm-run-progress__spinner';\n const messageEl = document.createElement('div');\n messageEl.className = 'twm-run-progress__message';\n messageEl.textContent = message;\n bodyEl.append(spinnerEl, messageEl);\n contentEl.appendChild(bodyEl);\n\n const job = mountJobProgress(contentEl, { progress, steps, spinner: spinnerEl });\n\n let stopBtn = null;\n if (typeof onCancel === 'function') {\n const stopActionsEl = document.createElement('div');\n stopActionsEl.className = 'twm-confirm-dialog__actions twm-run-progress__stop-actions';\n stopBtn = document.createElement('button');\n stopBtn.type = 'button';\n stopBtn.className = 'twm-confirm-dialog__btn twm-run-progress__stop-btn';\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">stop</span> Stop';\n stopBtn.addEventListener('click', () => {\n stopBtn.disabled = true;\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">hourglass_top</span> Stopping\u2026';\n onCancel();\n });\n stopActionsEl.appendChild(stopBtn);\n contentEl.appendChild(stopActionsEl);\n }\n\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-confirm-dialog__actions';\n actionsEl.style.display = 'none';\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-confirm-dialog__btn twm-confirm-dialog__btn--primary';\n closeBtn.textContent = 'Close';\n closeBtn.addEventListener('click', () => dialogWindow.close());\n actionsEl.appendChild(closeBtn);\n contentEl.appendChild(actionsEl);\n\n const finish = (status, text, cls) => {\n finished = true;\n spinnerEl.style.display = 'none';\n if (stopBtn) stopBtn.parentElement.style.display = 'none';\n messageEl.textContent = text;\n messageEl.className = `twm-run-progress__message ${cls}`;\n job.finish(status);\n actionsEl.style.display = '';\n settle({ status, message: text });\n };\n\n const dialogWindow = new ManagedWindow({\n id: dialogId,\n title,\n icon: 'play_arrow',\n content: contentEl,\n minWidth: 320,\n minHeight: 120,\n defaultWidth: 420,\n defaultHeight: 200 + (job.bar ? 40 : 0) + (job.steps ? 40 : 0),\n canMinimize: false,\n canMaximize: false,\n canResize: false,\n canDrag: false,\n modal: true,\n // BUG-0053. Focus goes to the window, never to Stop or Cancel: a stray\n // Enter or Space would cancel the run.\n focusOnOpen: 'window',\n onClose: () => {\n if (finished) return;\n finish('cancelled', 'Cancelled.', 'is-cancelled');\n },\n });\n dialogWindow.show();\n\n return {\n result,\n update(msg) {\n if (finished) return;\n messageEl.textContent = msg;\n },\n setProgress(next) {\n if (finished) return;\n job.setProgress(next);\n },\n setStep(which, opts) {\n if (finished) return;\n job.setStep(which, opts);\n },\n complete(res) {\n if (finished) return;\n finish(res?.ok ? 'done' : 'error', res?.message || '', res?.ok ? 'is-ok' : 'is-err');\n },\n cancelled(msg) {\n if (finished) return;\n finish('cancelled', msg || 'Cancelled.', 'is-cancelled');\n },\n close() {\n try { dialogWindow.close(); } catch { /* already closed */ }\n },\n };\n}\n", "/**\n * toast.js \u2014 thin wrapper around the mounted NotificationCenter for\n * callers that don't already hold an eventBus reference.\n *\n * The NotificationCenter (../notification_center.js) subscribes to\n * `toast:show` on its event bus; these helpers emit the same payload shape\n * on the bus they were given. They read no global: `NotificationCenter.mount()`\n * hands its bus to `setToastBus()`, and `dispose()` takes it back. An embedder\n * that wants toasts on some other bus calls `setToastBus(bus)` itself, and\n * `setToastBus(null)` to stop.\n *\n * Usage:\n * import { toastError, toastSuccess, toastWarn, toastInfo } from './toast.js';\n * toastError('Save failed', 'the server refused the change');\n *\n * The 1-arg form treats the string as the message (no title); the\n * 2-arg form is title + message. With no bus (no NotificationCenter mounted\n * yet, isolated test pages) the message goes to the console and nothing throws.\n */\n\nlet toastBus = null;\n\n/**\n * Route the toast helpers to `bus` (anything with `emit(name, payload)`), or\n * to the console with `null`. Returns the bus that was set before.\n */\nexport function setToastBus(bus) {\n const prev = toastBus;\n toastBus = bus && typeof bus.emit === 'function' ? bus : null;\n return prev;\n}\n\n/** The bus the toast helpers currently emit on, or null. */\nexport function getToastBus() {\n return toastBus;\n}\n\nfunction _emit(severity, persistent, titleOrMsg, msg) {\n const bus = toastBus;\n const title = (msg !== undefined) ? titleOrMsg : null;\n const message = (msg !== undefined) ? msg : titleOrMsg;\n if (!bus) {\n // Fall back to console so the message isn't lost if the bus is\n // unavailable (early bootstrap, isolated test pages).\n // eslint-disable-next-line no-console\n (severity === 'error' || severity === 'warn' ? console.warn : console.info)(\n `[toast/${severity}]`, title ? `${title}:` : '', message);\n return;\n }\n bus.emit('toast:show', {\n title, message, severity,\n persistent,\n durationMs: persistent ? 0 : 5000,\n });\n}\n\nexport function toastError(titleOrMsg, msg) { _emit('error', true, titleOrMsg, msg); }\nexport function toastWarn(titleOrMsg, msg) { _emit('warn', false, titleOrMsg, msg); }\nexport function toastInfo(titleOrMsg, msg) { _emit('info', false, titleOrMsg, msg); }\nexport function toastSuccess(titleOrMsg, msg) { _emit('success', false, titleOrMsg, msg); }\n\n/** Coerce a bridge-call result/exception into a user-facing error toast.\n * Drops the toast only if `res?.ok === false` *or* an exception was caught.\n * Returns true if the call succeeded (caller can continue), false otherwise. */\nexport function reportBridgeError(opName, resOrErr) {\n if (!resOrErr) return true;\n if (resOrErr instanceof Error) {\n toastError(opName, resOrErr.message || String(resOrErr));\n return false;\n }\n if (resOrErr && resOrErr.ok === false) {\n toastError(opName, resOrErr.error || 'operation refused');\n return false;\n }\n return true;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ collectFocusable,
3
+ openAnchoredLayer
4
+ } from "./chunk-Q7BALEPX.js";
5
+
6
+ // src/ui/components/popover.js
7
+ var OPEN = /* @__PURE__ */ new Set();
8
+ var nothingOpened = (toggled) => ({ el: null, close() {
9
+ }, closed: Promise.resolve(), reposition() {
10
+ }, toggled });
11
+ function keepTabInside(el) {
12
+ el.addEventListener("keydown", (ev) => {
13
+ if (ev.key !== "Tab" || ev.defaultPrevented) return;
14
+ const controls = collectFocusable(el);
15
+ if (!controls.length) {
16
+ ev.preventDefault();
17
+ return;
18
+ }
19
+ const first = controls[0];
20
+ const last = controls[controls.length - 1];
21
+ const active = el.ownerDocument.activeElement;
22
+ if (ev.shiftKey ? active === first || active === el : active === last) {
23
+ ev.preventDefault();
24
+ (ev.shiftKey ? last : first).focus();
25
+ }
26
+ });
27
+ }
28
+ function openPopover({
29
+ anchor,
30
+ content,
31
+ label = "",
32
+ className = "",
33
+ focus = null,
34
+ align = "start",
35
+ inside = null,
36
+ onClose = null
37
+ }) {
38
+ for (const open of OPEN) {
39
+ if (anchor && open.anchor === anchor) {
40
+ open.close("toggle");
41
+ return nothingOpened(true);
42
+ }
43
+ }
44
+ const el = document.createElement("div");
45
+ el.className = `twm-popover${className ? ` ${className}` : ""}`;
46
+ el.setAttribute("role", "dialog");
47
+ if (label) el.setAttribute("aria-label", label);
48
+ el.tabIndex = -1;
49
+ el.appendChild(content);
50
+ keepTabInside(el);
51
+ let settle;
52
+ const closed = new Promise((resolve) => {
53
+ settle = resolve;
54
+ });
55
+ const layer = openAnchoredLayer({
56
+ anchor,
57
+ el,
58
+ align,
59
+ gap: 4,
60
+ inside,
61
+ onClose(reason) {
62
+ OPEN.delete(handle);
63
+ anchor?.classList?.remove("twm-is-open");
64
+ anchor?.setAttribute?.("aria-expanded", "false");
65
+ onClose?.(reason);
66
+ settle();
67
+ }
68
+ });
69
+ if (!layer) return nothingOpened(false);
70
+ const handle = { el, anchor, closed, toggled: false, close: layer.close, reposition: layer.place };
71
+ OPEN.add(handle);
72
+ anchor?.classList?.add("twm-is-open");
73
+ if (anchor && !anchor.hasAttribute?.("aria-haspopup")) anchor.setAttribute?.("aria-haspopup", "dialog");
74
+ anchor?.setAttribute?.("aria-expanded", "true");
75
+ (focus || el).focus?.({ preventScroll: true });
76
+ return handle;
77
+ }
78
+
79
+ export {
80
+ openPopover
81
+ };
82
+ //# sourceMappingURL=chunk-DNJ3N4T4.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/ui/components/popover.js"],
4
+ "sourcesContent": ["/**\n * A POPOVER \u2014 a panel of rich content hung off the element that opened it. (0.18.0)\n *\n * `role=\"dialog\"`, on an anchored layer (`anchored_layer.js`, which says how it is\n * placed and what closes it). Focus moves into it on open and comes back to the\n * anchor on close. Opening one from the anchor that holds an open one closes it,\n * a toggle; opening one anywhere else closes the open one, unless that one owns\n * the new anchor (`anchored_layer.js`).\n *\n * TAB STAYS INSIDE, cycling the panel's controls, as a modal's and a `CategoryPicker`'s\n * do. The panel is mounted at the end of the page, so past its edge lies whatever comes\n * next in the document, which is not the anchor's neighbour and, over a modal, is behind\n * it. Escape is the way out.\n */\nimport { openAnchoredLayer } from './anchored_layer.js';\nimport { collectFocusable } from '../utils/focusable.js';\n\n/** The open popovers, to find the one an anchor holds. */\nconst OPEN = new Set();\n\n/** What a call answers when nothing opened. */\nconst nothingOpened = (toggled) => ({ el: null, close() {}, closed: Promise.resolve(), reposition() {}, toggled });\n\n/** Tab at the panel's edge goes round to the other edge. */\nfunction keepTabInside(el) {\n el.addEventListener('keydown', (ev) => {\n if (ev.key !== 'Tab' || ev.defaultPrevented) return;\n const controls = collectFocusable(el);\n if (!controls.length) { ev.preventDefault(); return; }\n const first = controls[0];\n const last = controls[controls.length - 1];\n const active = el.ownerDocument.activeElement;\n if (ev.shiftKey ? (active === first || active === el) : active === last) {\n ev.preventDefault();\n (ev.shiftKey ? last : first).focus();\n }\n });\n}\n\n/**\n * @param {object} o\n * @param {HTMLElement} o.anchor What opened it; focus returns here.\n * @param {HTMLElement} o.content The popover's body.\n * @param {string} [o.label] Its accessible name.\n * @param {string} [o.className] Extra classes on the panel.\n * @param {HTMLElement} [o.focus] What takes focus on open; else the panel.\n * @param {'start'|'end'} [o.align] Which anchor edge it lines up with first.\n * @param {string} [o.inside] A selector for floating things of your own that\n * are not \"outside\" it.\n * @param {(reason: string) => void} [o.onClose] After it is gone.\n * @returns {{el: HTMLElement|null, close: (reason?: string) => void, closed: Promise<void>,\n * reposition: () => void, toggled: boolean}}\n * `el` is null when nothing opened, and `onClose` is not called for it: `toggled`\n * is true when the call only CLOSED the popover its anchor held, false when\n * the anchor has left the document.\n */\nexport function openPopover({ anchor, content, label = '', className = '', focus = null, align = 'start',\n inside = null, onClose = null }) {\n for (const open of OPEN) {\n if (anchor && open.anchor === anchor) {\n open.close('toggle');\n return nothingOpened(true);\n }\n }\n\n const el = document.createElement('div');\n el.className = `twm-popover${className ? ` ${className}` : ''}`;\n el.setAttribute('role', 'dialog');\n if (label) el.setAttribute('aria-label', label);\n el.tabIndex = -1;\n el.appendChild(content);\n keepTabInside(el);\n\n let settle;\n const closed = new Promise((resolve) => { settle = resolve; });\n const layer = openAnchoredLayer({\n anchor, el, align, gap: 4, inside,\n onClose(reason) {\n OPEN.delete(handle);\n anchor?.classList?.remove('twm-is-open');\n anchor?.setAttribute?.('aria-expanded', 'false');\n onClose?.(reason);\n settle();\n },\n });\n if (!layer) return nothingOpened(false);\n const handle = { el, anchor, closed, toggled: false, close: layer.close, reposition: layer.place };\n OPEN.add(handle);\n anchor?.classList?.add('twm-is-open');\n if (anchor && !anchor.hasAttribute?.('aria-haspopup')) anchor.setAttribute?.('aria-haspopup', 'dialog');\n anchor?.setAttribute?.('aria-expanded', 'true');\n (focus || el).focus?.({ preventScroll: true });\n return handle;\n}\n"],
5
+ "mappings": ";;;;;;AAkBA,IAAM,OAAO,oBAAI,IAAI;AAGrB,IAAM,gBAAgB,CAAC,aAAa,EAAE,IAAI,MAAM,QAAQ;AAAC,GAAG,QAAQ,QAAQ,QAAQ,GAAG,aAAa;AAAC,GAAG,QAAQ;AAGhH,SAAS,cAAc,IAAI;AACvB,KAAG,iBAAiB,WAAW,CAAC,OAAO;AACnC,QAAI,GAAG,QAAQ,SAAS,GAAG,iBAAkB;AAC7C,UAAM,WAAW,iBAAiB,EAAE;AACpC,QAAI,CAAC,SAAS,QAAQ;AAAE,SAAG,eAAe;AAAG;AAAA,IAAQ;AACrD,UAAM,QAAQ,SAAS,CAAC;AACxB,UAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,UAAM,SAAS,GAAG,cAAc;AAChC,QAAI,GAAG,WAAY,WAAW,SAAS,WAAW,KAAM,WAAW,MAAM;AACrE,SAAG,eAAe;AAClB,OAAC,GAAG,WAAW,OAAO,OAAO,MAAM;AAAA,IACvC;AAAA,EACJ,CAAC;AACL;AAmBO,SAAS,YAAY;AAAA,EAAE;AAAA,EAAQ;AAAA,EAAS,QAAQ;AAAA,EAAI,YAAY;AAAA,EAAI,QAAQ;AAAA,EAAM,QAAQ;AAAA,EACnE,SAAS;AAAA,EAAM,UAAU;AAAK,GAAG;AAC3D,aAAW,QAAQ,MAAM;AACrB,QAAI,UAAU,KAAK,WAAW,QAAQ;AAClC,WAAK,MAAM,QAAQ;AACnB,aAAO,cAAc,IAAI;AAAA,IAC7B;AAAA,EACJ;AAEA,QAAM,KAAK,SAAS,cAAc,KAAK;AACvC,KAAG,YAAY,cAAc,YAAY,IAAI,SAAS,KAAK,EAAE;AAC7D,KAAG,aAAa,QAAQ,QAAQ;AAChC,MAAI,MAAO,IAAG,aAAa,cAAc,KAAK;AAC9C,KAAG,WAAW;AACd,KAAG,YAAY,OAAO;AACtB,gBAAc,EAAE;AAEhB,MAAI;AACJ,QAAM,SAAS,IAAI,QAAQ,CAAC,YAAY;AAAE,aAAS;AAAA,EAAS,CAAC;AAC7D,QAAM,QAAQ,kBAAkB;AAAA,IAC5B;AAAA,IAAQ;AAAA,IAAI;AAAA,IAAO,KAAK;AAAA,IAAG;AAAA,IAC3B,QAAQ,QAAQ;AACZ,WAAK,OAAO,MAAM;AAClB,cAAQ,WAAW,OAAO,aAAa;AACvC,cAAQ,eAAe,iBAAiB,OAAO;AAC/C,gBAAU,MAAM;AAChB,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACD,MAAI,CAAC,MAAO,QAAO,cAAc,KAAK;AACtC,QAAM,SAAS,EAAE,IAAI,QAAQ,QAAQ,SAAS,OAAO,OAAO,MAAM,OAAO,YAAY,MAAM,MAAM;AACjG,OAAK,IAAI,MAAM;AACf,UAAQ,WAAW,IAAI,aAAa;AACpC,MAAI,UAAU,CAAC,OAAO,eAAe,eAAe,EAAG,QAAO,eAAe,iBAAiB,QAAQ;AACtG,UAAQ,eAAe,iBAAiB,MAAM;AAC9C,GAAC,SAAS,IAAI,QAAQ,EAAE,eAAe,KAAK,CAAC;AAC7C,SAAO;AACX;",
6
+ "names": []
7
+ }
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-N7HC3ADV.js";
5
5
  import {
6
6
  DragReorder
7
- } from "./chunk-WUFLGETN.js";
7
+ } from "./chunk-WVFGV5FT.js";
8
8
 
9
9
  // src/ui/components/tabs.js
10
10
  var TAB_LEVELS = Object.freeze(["info", "warning", "alert"]);
@@ -372,4 +372,4 @@ export {
372
372
  TAB_LEVELS,
373
373
  createTabs
374
374
  };
375
- //# sourceMappingURL=chunk-REJ5HLIM.js.map
375
+ //# sourceMappingURL=chunk-HYJYYEPK.js.map
@@ -3,11 +3,13 @@ import {
3
3
  wheelStripSideways
4
4
  } from "./chunk-N7HC3ADV.js";
5
5
  import {
6
- DragReorder,
6
+ DragReorder
7
+ } from "./chunk-WVFGV5FT.js";
8
+ import {
7
9
  focusMenuItem,
8
10
  moveMenuFocus,
9
11
  placeMenuInViewport
10
- } from "./chunk-WUFLGETN.js";
12
+ } from "./chunk-QXAOTGCC.js";
11
13
 
12
14
  // src/editor/notebook_tab_bar.js
13
15
  var DEFAULT_TAB_DRAG_MIME = "application/x-flexdesk-tab";
@@ -474,4 +476,4 @@ export {
474
476
  getTabDragMime,
475
477
  NotebookTabBar
476
478
  };
477
- //# sourceMappingURL=chunk-7U4IB65H.js.map
479
+ //# sourceMappingURL=chunk-LLBJ2SJH.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/editor/notebook_tab_bar.js"],
4
4
  "sourcesContent": ["/**\n * NotebookTabBar \u2014 tab strip showing open files, with dirty indicators,\n * close buttons, drag-and-drop reordering, double-click rename, and\n * right-click context menu.\n *\n * Uses the same `.tab` / `.tab-title` / `.tab-dirty` / `.tab-close` DOM structure\n * as the flow-page tab bar, so all editor tab bars share a unified appearance.\n *\n * Calls back into parent via:\n * onActivate(filePath)\n * onClose(filePath)\n * onCloseOthers(filePath)\n * onCloseToRight(filePath)\n * onCloseAll()\n * onCloseSaved()\n * onRename(oldPath, newPath)\n * onDuplicate(filePath)\n * onReorder(orderedPaths)\n * onRevealInExplorer(filePath)\n * onSplitRight(filePath)\n * onMoveToOtherPane(filePath)\n * onDropFromOtherPane(filePath) \u2014 cross-pane drag-and-drop\n */\n\nimport { DragReorder } from '../ui/components/drag_reorder.js';\nimport { revealInStrip, wheelStripSideways } from '../ui/utils/strip_scroll.js';\nimport { placeMenuInViewport, moveMenuFocus, focusMenuItem } from '../ui/utils/menu_viewport.js';\n\n/** The MIME type a dragged editor tab carries when the embedder names none. */\nexport const DEFAULT_TAB_DRAG_MIME = 'application/x-flexdesk-tab';\n\n/** Custom MIME type so tab bars and editor panes recognise cross-pane drags. */\nlet _tabMime = DEFAULT_TAB_DRAG_MIME;\n\n/**\n * Name the MIME type editor tabs carry while dragged. Every NotebookTabBar and\n * EditorPane in the document reads it at drag time, so they always agree.\n * Call at boot, before the first drag.\n *\n * @param {string} [mime=DEFAULT_TAB_DRAG_MIME]\n */\nexport function setTabDragMime(mime = DEFAULT_TAB_DRAG_MIME) {\n _tabMime = (typeof mime === 'string' && mime) ? mime : DEFAULT_TAB_DRAG_MIME;\n}\n\n/** @returns {string} The MIME type editor tabs carry while dragged. */\nexport function getTabDragMime() {\n return _tabMime;\n}\n\nexport class NotebookTabBar {\n /** @type {HTMLElement} */\n #container = null;\n\n /** @type {object[]} [{filePath, label, fileType, isDirty}] */\n #tabs = [];\n\n /** @type {string|null} */\n #activeTab = null;\n\n /** @type {object} callbacks */\n #callbacks = {};\n\n // \u2500\u2500\u2500 Context menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** @type {HTMLElement|null} */\n #contextMenuEl = null;\n /** BUG-0040. What had focus when the menu opened. @type {Element|null} */\n #contextMenuReturnFocus = null;\n\n /** @type {Function|null} */\n #boundHideContextMenu = null;\n\n // \u2500\u2500\u2500 Drag and drop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Same-pane reorder. Cross-pane drops stay in this class's own\n * container handlers (#onStripDrag*).\n * @type {DragReorder|null} */\n #dragReorder = null;\n\n mount(container, callbacks = {}) {\n this.#container = container;\n this.#callbacks = callbacks;\n this.#container.className = 'tabs notebook-tabs';\n this.#boundHideContextMenu = () => this.#hideContextMenu();\n this.#installStripDnDHandlers();\n // NOT PASSIVE: it has to be able to take the wheel from the page.\n this.#container.addEventListener('wheel', this.#onWheel, { passive: false });\n this.#dragReorder = new DragReorder({\n container: this.#container,\n itemSelector: '.tab',\n keyAttr: 'path',\n axis: 'x',\n draggableGuard: (e) => {\n if (e.target.closest('.twm-tab-close')) return false;\n const title = e.target.closest('.tab')?.querySelector('.twm-tab-title');\n return title?.getAttribute('contenteditable') !== 'true';\n },\n onDragStart: (e, key, item) => {\n // Carry the cross-pane MIME so other panes accept this tab.\n try { e.dataTransfer.setData(_tabMime, key); } catch (_) {}\n // C33. \u2026AND LET THE HOST ADD ITS OWN, which is the whole of\n // what a second consumer of this strip needs from it.\n //\n // `DragReorder` publishes this hook for exactly this purpose\n // (\"host hook to augment dataTransfer (e.g. add a cross-pane\n // MIME)\", `../ui/components/drag_reorder.js`), and this class\n // consumed it and stopped there. The tile renderer mounts one\n // of these per tile and needs to mark the drag as one of ITS\n // tabs \u2014 a different question from \"is this an editor tab\",\n // asked of the same gesture.\n //\n // ADDITIVE BY CONSTRUCTION: the tab MIME is set first and\n // unchanged, so `EditorPane`'s existing cross-pane drop cannot\n // notice that anyone else is listening.\n try { this.#callbacks.onDragStart?.(e, key, item); }\n catch (err) { console.error('[tab-bar] onDragStart threw', err); }\n },\n onReorder: (order) => this.#callbacks.onReorder?.(order),\n });\n this.#render();\n }\n\n /**\n * Sync tabs from ProjectModel state.\n * @param {Array<{ filePath: string, fileType: string, isDirty: boolean }>} tabs\n * @param {string|null} activeFilePath\n */\n update(tabs, activeFilePath) {\n this.#tabs = tabs;\n this.#activeTab = activeFilePath;\n this.#render();\n }\n\n markDirty(filePath, isDirty) {\n const tab = this.#tabs.find(t => t.filePath === filePath);\n if (tab) {\n tab.isDirty = isDirty;\n this.#render();\n }\n }\n\n dispose() {\n this.#hideContextMenu();\n this.#removeStripDnDHandlers();\n this.#container?.removeEventListener('wheel', this.#onWheel);\n if (this.#revealFrame) cancelAnimationFrame(this.#revealFrame);\n this.#revealFrame = 0;\n this.#dragReorder?.destroy();\n this.#dragReorder = null;\n this.#container = null;\n }\n\n // Material symbol per file kind, merged over the generic set. The map used to\n // hardcode EcoAgent's kinds \u2014 `scenario`, `dashboard`, `model` \u2014 so a generic\n // tab bar knew one application's file taxonomy. Pass `fileTypeIcons` to add\n // your own.\n static #FILE_TYPE_ICONS = {\n module: 'extension',\n test: 'fact_check',\n diff: 'difference',\n unknown: 'description',\n };\n\n static #EXTRA_ICONS = {};\n\n /**\n * Add your application's file kinds to the tab-bar icon map.\n *\n * The map used to hardcode `scenario: 'science'`, `dashboard: 'dashboard'` and\n * `model: 'schema'` \u2014 EcoAgent's file taxonomy, baked into a generic tab bar.\n *\n * @param {Object.<string, string>} icons fileType -> material symbol name\n */\n static setFileTypeIcons(icons = {}) {\n NotebookTabBar.#EXTRA_ICONS = { ...icons };\n }\n\n static #iconFor(fileType) {\n return NotebookTabBar.#EXTRA_ICONS[fileType]\n ?? NotebookTabBar.#FILE_TYPE_ICONS[fileType]\n ?? NotebookTabBar.#FILE_TYPE_ICONS.unknown;\n }\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // Rendering\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n #render() {\n if (!this.#container) return;\n\n // THE STRIP KEEPS ITS SCROLL ACROSS A REBUILD. Emptying it shrinks its\n // scroll width to nothing, which clamps `scrollLeft` to 0 \u2014 so every\n // render (a tab activated, a title changed) threw a strip scrolled to\n // its tenth tab back to its first.\n const keepLeft = this.#container.scrollLeft;\n this.#container.innerHTML = '';\n\n for (const tab of this.#tabs) {\n const isActive = tab.filePath === this.#activeTab;\n const rawPath = tab.filePath.replace(/^(diff|builtin):\\/\\//, '');\n const label = tab.label\n ?? (tab.fileType === 'diff'\n ? `\u2194 ${rawPath.split('/').pop()}`\n : rawPath.split('/').pop().replace(/\\.[^.]+$/, ''));\n const icon = NotebookTabBar.#iconFor(tab.fileType);\n\n const tabEl = document.createElement('div');\n tabEl.className = `tab${isActive ? ' active' : ''}${tab.isPreview ? ' tab--preview' : ''}`;\n tabEl.dataset.path = tab.filePath;\n tabEl.title = tab.filePath;\n\n tabEl.innerHTML = `\n <span class=\"material-symbols-outlined tab-icon\">${icon}</span>\n <span class=\"twm-tab-title\">${this.#escHtml(label)}</span>\n ${tab.isDirty ? '<span class=\"tab-dirty\">\\u25cf</span>' : ''}\n ${tab.readonly ? '' : '<button class=\"twm-tab-close\" title=\"Close tab\" aria-label=\"Close tab\">\\u00d7</button>'}\n `;\n\n // Click \u2192 activate\n tabEl.addEventListener('click', (e) => {\n if (e.target.closest('.twm-tab-close')) return;\n if (tabEl.querySelector('.twm-tab-title')?.getAttribute('contenteditable') === 'true') return;\n this.#callbacks.onActivate?.(tab.filePath);\n });\n\n // Close button\n tabEl.querySelector('.twm-tab-close')?.addEventListener('click', (e) => {\n e.stopPropagation();\n this.#callbacks.onClose?.(tab.filePath);\n });\n\n // Double-click \u2192 inline rename\n tabEl.addEventListener('dblclick', (e) => {\n if (e.target.closest('.twm-tab-close')) return;\n this.#beginInlineRename(tab.filePath);\n });\n\n // F2 \u2192 inline rename\n tabEl.addEventListener('keydown', (e) => {\n if (e.key === 'F2') {\n e.preventDefault();\n this.#beginInlineRename(tab.filePath);\n }\n });\n\n // Context menu\n tabEl.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.#showContextMenu(e.clientX, e.clientY, tab.filePath);\n });\n\n this.#container.appendChild(tabEl);\n }\n // Make the freshly-rendered tabs draggable-to-reorder.\n this.#dragReorder?.attach();\n\n this.#container.scrollLeft = keepLeft;\n // A tab that has just BECOME active \u2014 opened, switched to, moved here\n // from another pane \u2014 is scrolled into the strip. Only then: a render\n // for any other reason (a title, a dirty dot) leaves the strip where the\n // reader put it, rather than yanking it back to the active tab.\n const revealKey = `${this.#activeTab}\\u0000${this.#tabs.length}`;\n if (revealKey !== this.#revealedKey) {\n this.#revealedKey = revealKey;\n this.#revealActive(true);\n }\n }\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // Scrolling (1.5) \u2014 the strip scrolls rather than wrapping or shrinking its\n // tabs, and hides its scrollbar (a bar in a 26px strip eats a third of every\n // label). So it owes a mouse user every other way in: a plain wheel, the\n // active tab brought into view, and \u2014 in `DragReorder._autoScrollEdge` \u2014\n // the edges scrolling while a tab is dragged toward them.\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n /** @type {string|null} the active tab + count last scrolled into view */\n #revealedKey = null;\n\n /** @type {number} a pending retry, for a strip not yet laid out */\n #revealFrame = 0;\n\n /** Bring the active tab fully into the strip (`revealInStrip`). */\n #revealActive(retry = false) {\n const el = this.#container;\n if (!el) return;\n const active = el.querySelector(':scope > .tab.active');\n if (!active) return;\n // Mounted but not laid out yet (the renderer updates a strip before it\n // attaches it). Once, on the next frame \u2014 not a loop.\n if (!revealInStrip(el, active) && retry && !this.#revealFrame\n && typeof requestAnimationFrame === 'function') {\n this.#revealFrame = requestAnimationFrame(() => {\n this.#revealFrame = 0;\n this.#revealActive(false);\n });\n }\n }\n\n /** A vertical wheel scrolls the strip sideways (`wheelStripSideways`). */\n #onWheel = (e) => wheelStripSideways(this.#container, e);\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // Drag and drop reordering (same-pane + cross-pane)\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n #installStripDnDHandlers() {\n if (!this.#container) return;\n this.#container.addEventListener('dragover', this.#onStripDragOver);\n this.#container.addEventListener('drop', this.#onStripDrop);\n this.#container.addEventListener('dragleave', this.#onStripDragLeave);\n }\n\n #removeStripDnDHandlers() {\n if (!this.#container) return;\n this.#container.removeEventListener('dragover', this.#onStripDragOver);\n this.#container.removeEventListener('drop', this.#onStripDrop);\n this.#container.removeEventListener('dragleave', this.#onStripDragLeave);\n }\n\n /** Check whether a drag event carries a cross-pane tab (not from this bar).\n *\n * C33. A HOST MAY NAME A SECOND MIME, at mount, as\n * `callbacks.externalTabMimes` \u2014 the tile renderer's tabs are not editor\n * tabs and do not carry the editor tab MIME (getTabDragMime()), so without this the\n * strip in tile B would refuse a tab dragged out of tile A's strip. Empty\n * by default, so every existing consumer keeps exactly today's admission\n * test.\n *\n * THE `isActive()` EARLY RETURN STAYS FIRST AND STAYS UNCHANGED. It is the\n * one line that keeps this bar's own reorder from being read as a foreign\n * drop, and no widening of the MIME list may be allowed to reach past it.\n *\n * Only `types` is consulted, never `getData` \u2014 under the HTML5 protected\n * mode `getData` returns the empty string for every event except `drop`,\n * so a payload read here would find nothing and arm nothing. */\n #isExternalTabDrag(e) {\n if (this.#dragReorder?.isActive()) return false; // same-pane drag is active\n const extra = Array.isArray(this.#callbacks.externalTabMimes)\n ? this.#callbacks.externalTabMimes : [];\n try {\n const types = e.dataTransfer.types;\n return types.includes(_tabMime) || extra.some((m) => types.includes(m));\n } catch { return false; }\n }\n\n // Same-pane reorder is handled by the shared DragReorder module (set\n // up in mount()). These container handlers cover ONLY cross-pane tab\n // drops \u2014 gated on `#isExternalTabDrag`, which defers while our own\n // reorder drag is active.\n\n #onStripDragOver = (e) => {\n if (this.#isExternalTabDrag(e)) {\n e.preventDefault();\n try { e.dataTransfer.dropEffect = 'move'; } catch (_) {}\n this.#container.classList.add('notebook-tabs--drop-target');\n }\n };\n\n #onStripDrop = (e) => {\n if (this.#isExternalTabDrag(e)) {\n e.preventDefault();\n this.#container.classList.remove('notebook-tabs--drop-target');\n const filePath = e.dataTransfer.getData(_tabMime) || e.dataTransfer.getData('text/plain');\n if (filePath) {\n this.#callbacks.onDropFromOtherPane?.(filePath);\n }\n }\n };\n\n #onStripDragLeave = (e) => {\n if (!this.#container.contains(e.relatedTarget)) {\n this.#container.classList.remove('notebook-tabs--drop-target');\n }\n };\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // Context menu\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n #showContextMenu(x, y, filePath) {\n this.#hideContextMenu();\n\n const idx = this.#tabs.findIndex(t => t.filePath === filePath);\n const total = this.#tabs.length;\n\n const allItems = [\n { label: 'Rename', icon: 'edit', action: 'rename', shortcut: 'F2' },\n { label: 'Duplicate', icon: 'content_copy', action: 'duplicate' },\n { separator: true },\n { label: 'Split Right', icon: 'vertical_split', action: 'split-right', shortcut: 'Ctrl+\\\\' },\n { label: 'Move to Other Pane',icon: 'swap_horiz', action: 'move-to-other' },\n { separator: true },\n { label: 'Close', icon: 'close', action: 'close', danger: true },\n { label: 'Close Others', icon: 'close_fullscreen', action: 'close-others', danger: true, disabled: total <= 1 },\n { label: 'Close to the Right',icon: 'tab_close', action: 'close-right', danger: true, disabled: idx === -1 || idx >= total - 1 },\n { label: 'Close All', icon: 'tab_close_inactive', action: 'close-all', danger: true },\n { label: 'Close Saved', icon: 'check_circle', action: 'close-saved', danger: true },\n { separator: true },\n { label: 'Reveal in Explorer', icon: 'folder_open', action: 'reveal' },\n ];\n\n const menuFilter = this.#callbacks.menuFilter;\n const items = menuFilter\n ? allItems.filter(item => item.separator || menuFilter(item.action, filePath) !== false)\n : allItems;\n\n // Collapse consecutive / leading / trailing separators\n const cleaned = [];\n for (const item of items) {\n if (item.separator) {\n if (cleaned.length > 0 && !cleaned[cleaned.length - 1].separator) cleaned.push(item);\n } else {\n cleaned.push(item);\n }\n }\n while (cleaned.length > 0 && cleaned[cleaned.length - 1].separator) cleaned.pop();\n\n const menu = document.createElement('div');\n menu.className = 'nb-context-menu';\n menu.setAttribute('role', 'menu');\n\n for (const item of cleaned) {\n if (item.separator) {\n const sep = document.createElement('div');\n sep.className = 'nb-context-menu__separator';\n menu.appendChild(sep);\n continue;\n }\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('role', 'menuitem');\n btn.className = 'nb-context-menu__item';\n if (item.danger) btn.classList.add('nb-context-menu__item--danger');\n if (item.disabled) btn.classList.add('nb-context-menu__item--disabled');\n\n btn.innerHTML = `<span class=\"material-symbols-outlined\">${item.icon}</span><span>${this.#escHtml(item.label)}</span>${\n item.shortcut ? `<span class=\"nb-context-menu__shortcut\">${item.shortcut}</span>` : ''\n }`;\n\n if (!item.disabled) {\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.#hideContextMenu();\n this.#handleContextMenuAction(item.action, filePath);\n });\n }\n menu.appendChild(btn);\n }\n\n this.#contextMenuReturnFocus = document.activeElement;\n document.body.appendChild(menu);\n this.#contextMenuEl = menu;\n\n // BUG-0040. Inside the window, at most its height, scrolling when\n // longer; the keyboard starts on the first item it can use.\n placeMenuInViewport(menu, x, y);\n focusMenuItem(this.#contextMenuItems()[0]);\n\n // Animate in\n requestAnimationFrame(() => menu.classList.add('visible'));\n\n // Dismiss on outside click or Escape\n setTimeout(() => {\n document.addEventListener('click', this.#boundHideContextMenu, true);\n document.addEventListener('contextmenu', this.#boundHideContextMenu, true);\n }, 0);\n document.addEventListener('keydown', this.#onKeyDown);\n }\n\n #hideContextMenu() {\n if (!this.#contextMenuEl) return;\n const returnTo = this.#contextMenuReturnFocus;\n const held = this.#contextMenuEl.contains(document.activeElement);\n this.#contextMenuEl.remove();\n this.#contextMenuEl = null;\n this.#contextMenuReturnFocus = null;\n document.removeEventListener('click', this.#boundHideContextMenu, true);\n document.removeEventListener('contextmenu', this.#boundHideContextMenu, true);\n document.removeEventListener('keydown', this.#onKeyDown);\n if (held && returnTo?.isConnected) returnTo.focus?.({ preventScroll: true });\n }\n\n /** BUG-0040. The menu's items the keyboard can land on. */\n #contextMenuItems() {\n return this.#contextMenuEl\n ? [...this.#contextMenuEl.querySelectorAll('.nb-context-menu__item:not(.nb-context-menu__item--disabled)')]\n : [];\n }\n\n #onKeyDown = (e) => {\n if (e.key === 'Escape') { this.#hideContextMenu(); return; }\n // BUG-0040. Up/Down/Home/End move between the items and scroll the\n // focused one into view; Enter and Space are the buttons' own.\n moveMenuFocus(e, this.#contextMenuItems());\n };\n\n #handleContextMenuAction(action, filePath) {\n switch (action) {\n case 'rename': this.#beginInlineRename(filePath); break;\n case 'duplicate': this.#callbacks.onDuplicate?.(filePath); break;\n case 'close': this.#callbacks.onClose?.(filePath); break;\n case 'close-others': this.#callbacks.onCloseOthers?.(filePath); break;\n case 'close-right': this.#callbacks.onCloseToRight?.(filePath); break;\n case 'close-all': this.#callbacks.onCloseAll?.(); break;\n case 'close-saved': this.#callbacks.onCloseSaved?.(); break;\n case 'split-right': this.#callbacks.onSplitRight?.(filePath); break;\n case 'move-to-other':this.#callbacks.onMoveToOtherPane?.(filePath); break;\n case 'reveal': this.#callbacks.onRevealInExplorer?.(filePath); break;\n }\n }\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // Inline rename (contenteditable on tab title)\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n #beginInlineRename(filePath) {\n const tabEl = this.#container?.querySelector(`.tab[data-path=\"${CSS.escape(filePath)}\"]`);\n if (!tabEl) return;\n\n const title = tabEl.querySelector('.twm-tab-title');\n if (!title || title.getAttribute('contenteditable') === 'true') return;\n\n const tab = this.#tabs.find(t => t.filePath === filePath);\n if (!tab) return;\n\n // model.notebook, builtin, and readonly files cannot be renamed\n if (tab.fileType === 'model') return;\n if (filePath.startsWith('builtin://')) return;\n if (tab.readonly) return;\n\n const original = title.textContent || '';\n title.setAttribute('contenteditable', 'true');\n title.focus();\n\n try {\n const range = document.createRange();\n range.selectNodeContents(title);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } catch (_) { /* ignore */ }\n\n let committed = false;\n\n const finish = (commit) => {\n if (committed) return;\n committed = true;\n\n const newName = (title.textContent || '').trim();\n title.removeAttribute('contenteditable');\n title.removeEventListener('keydown', onKeyDown);\n title.removeEventListener('blur', onBlur, true);\n\n try { window.getSelection()?.removeAllRanges?.(); } catch (_) { /* ignore */ }\n\n if (commit && newName && newName !== original && /^[\\w][\\w.-]*$/.test(newName)) {\n title.textContent = newName;\n const dir = filePath.split('/').slice(0, -1).join('/');\n const ext = filePath.split('.').pop();\n const newPath = `${dir}/${newName}.${ext}`;\n this.#callbacks.onRename?.(filePath, newPath);\n } else {\n title.textContent = original;\n }\n };\n\n const onKeyDown = (e) => {\n if (e.key === 'Enter') { e.preventDefault(); finish(true); }\n else if (e.key === 'Escape') { e.preventDefault(); finish(false); }\n e.stopPropagation();\n };\n\n const onBlur = () => finish(true);\n\n title.addEventListener('keydown', onKeyDown);\n title.addEventListener('blur', onBlur, true);\n }\n\n #escHtml(s) {\n return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n}\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  DataTable,
3
3
  createRafResizeObserver
4
- } from "./chunk-2Z2ENHR3.js";
4
+ } from "./chunk-U5GKJUOC.js";
5
+ import {
6
+ ManagedWindow
7
+ } from "./chunk-ZL3VKINP.js";
5
8
  import {
6
- ManagedWindow,
7
9
  flatChoices,
8
10
  selectBox
9
- } from "./chunk-PGZ4EHSE.js";
11
+ } from "./chunk-Q7BALEPX.js";
10
12
 
11
13
  // src/charts/plotly_wrapper.js
12
14
  var _plotlySrc = null;
@@ -2851,4 +2853,4 @@ export {
2851
2853
  openPlotPopoutWindow,
2852
2854
  openRawTracesWindow
2853
2855
  };
2854
- //# sourceMappingURL=chunk-7OL6F2AM.js.map
2856
+ //# sourceMappingURL=chunk-P74F6I6P.js.map