gloomberb 0.17.5 → 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 (922) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/package.json +8 -1
  4. package/patches/electrobun@1.18.1.patch +74 -0
  5. package/src/account/auth-model.ts +3 -2
  6. package/src/account/device-signin-dialog.tsx +38 -13
  7. package/src/account/device-signin.ts +2 -1
  8. package/src/account/upgrade-dialog.tsx +6 -2
  9. package/src/api-client/askg.ts +5 -3
  10. package/src/api-client/bank-figures.ts +73 -0
  11. package/src/api-client/chat.ts +9 -0
  12. package/src/api-client/commodity-balances.ts +77 -0
  13. package/src/api-client/credit-boards.ts +21 -1
  14. package/src/api-client/crypto-markets.ts +88 -1
  15. package/src/api-client/data.ts +135 -6
  16. package/src/api-client/debt-maturities.ts +18 -0
  17. package/src/api-client/earnings.ts +10 -0
  18. package/src/api-client/equity-screener.ts +3 -0
  19. package/src/api-client/errors.ts +13 -0
  20. package/src/api-client/fund-facts.ts +72 -0
  21. package/src/api-client/futures-curve.ts +26 -3
  22. package/src/api-client/geo.ts +11 -1
  23. package/src/api-client/index.ts +30 -2
  24. package/src/api-client/insider-signals.ts +159 -0
  25. package/src/api-client/market-discovery.ts +1 -1
  26. package/src/api-client/normalizers.ts +2 -0
  27. package/src/api-client/paths.ts +28 -0
  28. package/src/api-client/request.ts +11 -3
  29. package/src/api-client/research-activity.ts +15 -8
  30. package/src/api-client/socket.ts +16 -3
  31. package/src/api-client/supply-chain-graph.ts +2 -2
  32. package/src/api-client/supply-chain.ts +8 -0
  33. package/src/api-client/tape.ts +12 -0
  34. package/src/api-client/types.ts +91 -3
  35. package/src/api-client/upgrade-experiment.ts +4 -3
  36. package/src/api-client/wall-experiments.ts +5 -3
  37. package/src/api-client/wall-summary.ts +3 -1
  38. package/src/api-client/web-experiments.ts +5 -2
  39. package/src/api-client/yield-curves.ts +17 -0
  40. package/src/app/command-bar-intro.ts +38 -0
  41. package/src/app/keybindings/actions.ts +1 -1
  42. package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
  43. package/src/app/pane-runtime/plugin-bindings.ts +4 -0
  44. package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
  45. package/src/app/pane-runtime/ticker-open-target.ts +31 -0
  46. package/src/app/runtime/broker-import.ts +23 -21
  47. package/src/app/runtime/desktop-deeplink.ts +3 -4
  48. package/src/app/runtime/plugin-bindings.ts +16 -9
  49. package/src/app/runtime/startup.ts +3 -4
  50. package/src/app/runtime/ticker-refresh.ts +13 -12
  51. package/src/app/runtime/update.ts +17 -3
  52. package/src/architecture/core-builtin-allowlist.json +2 -13
  53. package/src/architecture/silent-catch-allowlist.json +3 -0
  54. package/src/architecture/ui-literals-allowlist.json +186 -0
  55. package/src/architecture/ui-tokens-allowlist.json +40 -0
  56. package/src/ask-gloom/pane-context.ts +3 -1
  57. package/src/brokers/broker-portfolio-sync.ts +66 -0
  58. package/src/brokers/signed-in/catalog.ts +2 -1
  59. package/src/brokers/signed-in/client.ts +7 -2
  60. package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
  61. package/src/brokers/signed-in/sign-in.ts +22 -20
  62. package/src/brokers/sync-broker-instance.ts +77 -42
  63. package/src/capabilities/chart-series.ts +2 -0
  64. package/src/capabilities/registry.ts +1 -3
  65. package/src/cli/bank-section.ts +147 -0
  66. package/src/cli/base-converter.ts +5 -2
  67. package/src/cli/board-coins.ts +70 -0
  68. package/src/cli/commands/fred-series.ts +90 -0
  69. package/src/cli/commands/market.ts +434 -96
  70. package/src/cli/commands/news-search.ts +35 -2
  71. package/src/cli/commands/options-chain.ts +25 -9
  72. package/src/cli/commands/options-leaps.ts +3 -3
  73. package/src/cli/commands/overview.ts +130 -40
  74. package/src/cli/commands/plugins.ts +1 -0
  75. package/src/cli/commands/search.ts +87 -24
  76. package/src/cli/commands/system.ts +5 -2
  77. package/src/cli/commands/ticker.ts +361 -64
  78. package/src/cli/context.ts +15 -1
  79. package/src/cli/desktop-pane-shot.ts +11 -3
  80. package/src/cli/earnings-calendar.ts +2 -1
  81. package/src/cli/errors.ts +25 -2
  82. package/src/cli/export-source.ts +18 -3
  83. package/src/cli/fx-pair.ts +77 -0
  84. package/src/cli/glossary.ts +196 -14
  85. package/src/cli/history-rows.ts +84 -19
  86. package/src/cli/index-roots.ts +26 -0
  87. package/src/cli/index.ts +57 -20
  88. package/src/cli/known-gaps.ts +156 -22
  89. package/src/cli/listing-arg.ts +217 -150
  90. package/src/cli/listing-suggestion.ts +7 -23
  91. package/src/cli/name-entries.ts +76 -0
  92. package/src/cli/not-a-ticker.ts +15 -6
  93. package/src/cli/pane-functions/access-gate.ts +22 -0
  94. package/src/cli/pane-functions/capabilities.ts +62 -4
  95. package/src/cli/pane-functions/catalog.ts +144 -39
  96. package/src/cli/pane-functions/data.ts +6 -5
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +3 -3
  99. package/src/cli/pane-functions/freshness.ts +93 -17
  100. package/src/cli/pane-functions/function-help.ts +20 -17
  101. package/src/cli/pane-functions/headless.ts +187 -40
  102. package/src/cli/pane-functions/index.ts +126 -12
  103. package/src/cli/pane-functions/options.ts +17 -3
  104. package/src/cli/pane-functions/report-notices.ts +17 -3
  105. package/src/cli/pane-functions/resolver.ts +74 -18
  106. package/src/cli/pane-functions/screenshot.ts +126 -23
  107. package/src/cli/pane-functions/shot-options.ts +68 -0
  108. package/src/cli/perpetual-contract.ts +3 -1
  109. package/src/cli/report-tables.ts +21 -6
  110. package/src/cli/result.ts +2 -0
  111. package/src/cli/series-search.ts +6 -1
  112. package/src/cli/staged-tickers.ts +5 -0
  113. package/src/cli/statement-filings.ts +261 -0
  114. package/src/cli/symbol-args.ts +47 -8
  115. package/src/cli/symbol-list.ts +9 -2
  116. package/src/cli/symbol-rows.ts +269 -29
  117. package/src/cli/ticker-resolution.ts +148 -35
  118. package/src/cli/treasury-yields.ts +86 -0
  119. package/src/cli/types.ts +3 -0
  120. package/src/cli/uncovered-instrument.ts +20 -0
  121. package/src/cli/unknown-command.ts +18 -0
  122. package/src/components/chart/composite/axis-overlays.tsx +16 -9
  123. package/src/components/chart/composite/composite-chart.tsx +163 -23
  124. package/src/components/chart/composite/downsample.ts +19 -3
  125. package/src/components/chart/composite/format.ts +13 -0
  126. package/src/components/chart/composite/legend.tsx +161 -68
  127. package/src/components/chart/composite/panel-bitmap.ts +8 -2
  128. package/src/components/chart/composite/panel-labels.ts +38 -0
  129. package/src/components/chart/composite/panel-series.ts +1 -0
  130. package/src/components/chart/composite/panel-surface.tsx +28 -10
  131. package/src/components/chart/composite/price-axis-labels.tsx +16 -3
  132. package/src/components/chart/composite/scene.ts +60 -2
  133. package/src/components/chart/composite/series-axis-tags.tsx +67 -0
  134. package/src/components/chart/composite/toolbar.tsx +12 -7
  135. package/src/components/chart/composite/tools.ts +2 -2
  136. package/src/components/chart/composite/types.ts +34 -0
  137. package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
  138. package/src/components/chart/core/view-reset.ts +46 -0
  139. package/src/components/chart/curve/curve-surface.tsx +1 -1
  140. package/src/components/chart/static/series.ts +39 -0
  141. package/src/components/chart/static/trail-chart-surface.tsx +2 -1
  142. package/src/components/command-bar/commands/collection-list.ts +45 -15
  143. package/src/components/command-bar/commands/collection.ts +11 -4
  144. package/src/components/command-bar/commands/direct/index.ts +1 -1
  145. package/src/components/command-bar/commands/registry.ts +2 -2
  146. package/src/components/command-bar/list/badge.ts +4 -3
  147. package/src/components/command-bar/list/model.ts +12 -0
  148. package/src/components/command-bar/list/view.tsx +1 -1
  149. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  150. package/src/components/command-bar/panel/index.tsx +19 -8
  151. package/src/components/command-bar/panel/native-surface.ts +6 -4
  152. package/src/components/command-bar/panel/prompt-example.ts +22 -0
  153. package/src/components/command-bar/routes/root/command-items.ts +1 -1
  154. package/src/components/command-bar/routes/root/pick-prefetch.ts +38 -0
  155. package/src/components/command-bar/routes/root/provider-search.ts +9 -9
  156. package/src/components/command-bar/routes/root/results.ts +13 -0
  157. package/src/components/command-bar/routes/root/runtime.ts +3 -0
  158. package/src/components/command-bar/routes/root/shortcut-feedback.ts +3 -1
  159. package/src/components/command-bar/routes/root/shortcut-items.ts +1 -1
  160. package/src/components/command-bar/routes/root/start-here.ts +90 -0
  161. package/src/components/command-bar/routes/ticker-search/actions.ts +34 -0
  162. package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
  163. package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
  164. package/src/components/command-bar/surface/index.tsx +5 -0
  165. package/src/components/command-bar/theme-picker.tsx +3 -1
  166. package/src/components/command-bar/workflow/builtin.ts +5 -1
  167. package/src/components/command-bar/workflow/collection-actions.ts +23 -13
  168. package/src/components/command-bar/workflow/ops.ts +25 -3
  169. package/src/components/command-bar/workflow/pane-reuse.ts +3 -2
  170. package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
  171. package/src/components/command-bar/workflow/tickers.ts +7 -5
  172. package/src/components/feedback-dialog.tsx +1 -1
  173. package/src/components/form-modal/broker-step.tsx +7 -63
  174. package/src/components/form-modal/content.tsx +7 -2
  175. package/src/components/form-modal/field-row.tsx +6 -8
  176. package/src/components/form-modal/host.tsx +3 -3
  177. package/src/components/form-modal/model.ts +3 -0
  178. package/src/components/form-modal/routes.ts +17 -2
  179. package/src/components/index.ts +6 -6
  180. package/src/components/input-search-bar.tsx +43 -6
  181. package/src/components/layout/detached-pane-shell.tsx +0 -1
  182. package/src/components/layout/floating-pane.tsx +0 -1
  183. package/src/components/layout/header.tsx +8 -7
  184. package/src/components/layout/pane/content.tsx +11 -8
  185. package/src/components/layout/pane/footer/index.tsx +7 -4
  186. package/src/components/layout/pane/footer/model.ts +28 -2
  187. package/src/components/layout/pane/header.tsx +9 -19
  188. package/src/components/layout/pane/index.tsx +0 -1
  189. package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
  190. package/src/components/layout/pane/pane-tabs.tsx +4 -3
  191. package/src/components/layout/pane/sizing.ts +9 -0
  192. package/src/components/layout/pane/ticker-fate-gate.tsx +62 -0
  193. package/src/components/layout/shell/pane/capture.ts +44 -20
  194. package/src/components/layout/status-bar.tsx +3 -6
  195. package/src/components/markdown-text.tsx +17 -2
  196. package/src/components/market-board/index.tsx +19 -8
  197. package/src/components/metric-treemap/heat-surface.tsx +2 -7
  198. package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
  199. package/src/components/onboarding/onboarding-frame.tsx +24 -21
  200. package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
  201. package/src/components/onboarding/wizard-model.ts +1 -1
  202. package/src/components/onboarding/wizard-positions.ts +56 -19
  203. package/src/components/pane-settings-dialog/desktop.tsx +12 -50
  204. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
  205. package/src/components/price-performance.tsx +18 -2
  206. package/src/components/reader/article-reader.tsx +11 -10
  207. package/src/components/reader/detail-reader.tsx +9 -5
  208. package/src/components/reader/reader-text.tsx +51 -24
  209. package/src/components/sign-in-code-panel.tsx +129 -75
  210. package/src/components/ticker/badge/format.ts +64 -15
  211. package/src/components/ticker/badge/index.tsx +33 -11
  212. package/src/components/ticker/badge/list.tsx +4 -3
  213. package/src/components/ticker/badge/text.tsx +2 -2
  214. package/src/components/ticker/list-table-view.tsx +8 -1
  215. package/src/components/ui/action-row.tsx +5 -2
  216. package/src/components/ui/audio-player.tsx +70 -0
  217. package/src/components/ui/card.tsx +75 -0
  218. package/src/components/ui/data-table/index.tsx +4 -2
  219. package/src/components/ui/data-table/opentui/index.tsx +61 -20
  220. package/src/components/ui/data-table/opentui/model.ts +104 -0
  221. package/src/components/ui/data-table/types.ts +11 -0
  222. package/src/components/ui/detail-scroll-body.tsx +1 -1
  223. package/src/components/ui/dialog-actions.tsx +1 -21
  224. package/src/components/ui/display.tsx +13 -5
  225. package/src/components/ui/external-link.tsx +4 -2
  226. package/src/components/ui/fields.tsx +12 -0
  227. package/src/components/ui/figure.tsx +5 -3
  228. package/src/components/ui/frame.tsx +40 -6
  229. package/src/components/ui/icon.tsx +4 -0
  230. package/src/components/ui/index.ts +4 -1
  231. package/src/components/ui/inline-quick-add.tsx +4 -1
  232. package/src/components/ui/list-view.tsx +8 -0
  233. package/src/components/ui/prose.tsx +97 -25
  234. package/src/components/ui/query-bar-keys.tsx +32 -6
  235. package/src/components/ui/query-bar.tsx +35 -4
  236. package/src/components/ui/quote.ts +42 -0
  237. package/src/components/ui/range-track.tsx +15 -2
  238. package/src/components/ui/reveal-in-scroll-box.ts +21 -3
  239. package/src/components/ui/select-button.tsx +38 -3
  240. package/src/components/ui/status.tsx +73 -4
  241. package/src/components/ui/table-layout.ts +20 -0
  242. package/src/components/ui/windowed-list.tsx +27 -0
  243. package/src/components/use-pinned-moment.ts +19 -0
  244. package/src/core/app-runtime.ts +2 -2
  245. package/src/core/state/app/instrument.ts +18 -1
  246. package/src/core/state/app/layout.ts +6 -0
  247. package/src/core/state/app/state.ts +14 -2
  248. package/src/data/cached-query.ts +1 -1
  249. package/src/data/config/chart-settings.ts +3 -1
  250. package/src/data/config/home.ts +4 -1
  251. package/src/data/config/store/node.ts +9 -4
  252. package/src/data/config/store/normalize.ts +9 -0
  253. package/src/data/json-storage.ts +6 -3
  254. package/src/data/json-ticker-repository.ts +3 -1
  255. package/src/data/plugin-cache.ts +5 -1
  256. package/src/data/sqlite/json.ts +3 -1
  257. package/src/data/ticker-repository.ts +5 -2
  258. package/src/docs/snapshot.json +248 -5
  259. package/src/feedback/diagnostics.ts +2 -6
  260. package/src/i18n/es.ts +86 -6
  261. package/src/i18n/index.ts +3 -9
  262. package/src/i18n/ja.ts +86 -6
  263. package/src/i18n/ko.ts +86 -6
  264. package/src/i18n/zh-cn.ts +86 -6
  265. package/src/i18n/zh-tw.ts +86 -6
  266. package/src/layout-marketplace/cloud.ts +16 -5
  267. package/src/layout-marketplace/gallery-desktop.tsx +8 -4
  268. package/src/layout-marketplace/gallery.tsx +4 -4
  269. package/src/layout-marketplace/linked-sync.ts +9 -3
  270. package/src/layout-marketplace/linked.ts +24 -3
  271. package/src/layout-marketplace/model.ts +39 -4
  272. package/src/market-data/bars-per-year.ts +43 -0
  273. package/src/market-data/bond-funds.ts +85 -0
  274. package/src/market-data/coordinator/auxiliary.ts +5 -2
  275. package/src/market-data/coordinator/index.ts +39 -5
  276. package/src/market-data/futures-contract.ts +155 -5
  277. package/src/market-data/hooks.tsx +77 -12
  278. package/src/market-data/market/bar-period.ts +107 -0
  279. package/src/market-data/market/format.ts +18 -14
  280. package/src/market-data/market/freshness.ts +29 -4
  281. package/src/market-data/market/index-level.ts +51 -0
  282. package/src/market-data/market/status.ts +152 -13
  283. package/src/market-data/model-dividend-yield.ts +117 -0
  284. package/src/market-data/quotes/freshness.ts +30 -1
  285. package/src/{plugins/builtin/portfolio-list → market-data/quotes}/live-valuation.ts +52 -6
  286. package/src/market-data/quotes/regular-session-valuation.ts +32 -1
  287. package/src/market-data/realized-volatility.ts +16 -7
  288. package/src/market-data/tax-equivalent.ts +344 -0
  289. package/src/news/aggregator.ts +4 -2
  290. package/src/notifications/notification-log.ts +5 -3
  291. package/src/plugins/auto-update-node.ts +1 -0
  292. package/src/plugins/builtin/account-management/footer.ts +1 -1
  293. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  294. package/src/plugins/builtin/account-management/model.ts +1 -0
  295. package/src/plugins/builtin/account-management/pane.tsx +71 -19
  296. package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
  297. package/src/plugins/builtin/alerts/cli.ts +7 -18
  298. package/src/plugins/builtin/alerts/constants.ts +8 -0
  299. package/src/plugins/builtin/alerts/event-rows.ts +16 -0
  300. package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
  301. package/src/plugins/builtin/alerts/headless.ts +182 -0
  302. package/src/plugins/builtin/alerts/index.tsx +3 -0
  303. package/src/plugins/builtin/alerts/pane.tsx +1 -7
  304. package/src/plugins/builtin/alerts/storage.ts +17 -1
  305. package/src/plugins/builtin/analytics/index.tsx +6 -1
  306. package/src/plugins/builtin/analytics/metrics.ts +55 -13
  307. package/src/plugins/builtin/analytics/risk-headless.ts +26 -7
  308. package/src/plugins/builtin/analytics/risk-math.ts +83 -0
  309. package/src/plugins/builtin/analytics/risk-model.ts +171 -19
  310. package/src/plugins/builtin/analytics/risk-pane.tsx +17 -12
  311. package/src/plugins/builtin/analytics/sector-model.ts +14 -3
  312. package/src/plugins/builtin/awards/headless.ts +6 -5
  313. package/src/plugins/builtin/awards/index.tsx +1 -1
  314. package/src/plugins/builtin/backtest/client.ts +38 -8
  315. package/src/plugins/builtin/backtest/engine.ts +25 -13
  316. package/src/plugins/builtin/backtest/export.ts +27 -0
  317. package/src/plugins/builtin/backtest/format.ts +19 -3
  318. package/src/plugins/builtin/backtest/headless.ts +42 -28
  319. package/src/plugins/builtin/backtest/index.tsx +3 -0
  320. package/src/plugins/builtin/backtest/pane.tsx +39 -10
  321. package/src/plugins/builtin/backtest/report.ts +160 -0
  322. package/src/plugins/builtin/backtest/rules.ts +2 -0
  323. package/src/plugins/builtin/backtest/window.ts +112 -0
  324. package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
  325. package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
  326. package/src/plugins/builtin/builtin-plugin-meta.ts +0 -1
  327. package/src/plugins/builtin/catalysts/headless.ts +24 -13
  328. package/src/plugins/builtin/catalysts/index.tsx +4 -2
  329. package/src/plugins/builtin/catalysts/model.ts +18 -1
  330. package/src/plugins/builtin/catalysts/pane.tsx +2 -2
  331. package/src/plugins/builtin/cds/client.ts +28 -5
  332. package/src/plugins/builtin/cds/headless.ts +183 -31
  333. package/src/plugins/builtin/cds/index.tsx +1 -1
  334. package/src/plugins/builtin/cds/model.ts +229 -53
  335. package/src/plugins/builtin/cds/pane.tsx +82 -26
  336. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
  337. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
  338. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
  339. package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
  340. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
  341. package/src/plugins/builtin/chart-composer/editor/controller.ts +14 -10
  342. package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
  343. package/src/plugins/builtin/chart-composer/formula.ts +233 -0
  344. package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
  345. package/src/plugins/builtin/chart-composer/headless.ts +117 -15
  346. package/src/plugins/builtin/chart-composer/index.tsx +73 -15
  347. package/src/plugins/builtin/chart-composer/pane.tsx +86 -23
  348. package/src/plugins/builtin/chart-composer/presets.ts +165 -8
  349. package/src/plugins/builtin/chart-composer/quick-add.tsx +9 -2
  350. package/src/plugins/builtin/chart-composer/series-catalog.ts +85 -16
  351. package/src/plugins/builtin/chart-composer/series-expression.ts +10 -8
  352. package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
  353. package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
  354. package/src/plugins/builtin/chart-composer/settings.ts +16 -4
  355. package/src/plugins/builtin/chart-composer/studies.ts +1 -1
  356. package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
  357. package/src/plugins/builtin/chat/content/channel-navigation.ts +17 -6
  358. package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
  359. package/src/plugins/builtin/chat/content/composer.tsx +22 -1
  360. package/src/plugins/builtin/chat/content/index.tsx +47 -10
  361. package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
  362. package/src/plugins/builtin/chat/content/mentions.ts +50 -21
  363. package/src/plugins/builtin/chat/content/scroll.ts +12 -5
  364. package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
  365. package/src/plugins/builtin/chat/content/snapshot.ts +40 -6
  366. package/src/plugins/builtin/chat/content/transcript.tsx +48 -37
  367. package/src/plugins/builtin/chat/content/whole-message-copy.ts +44 -2
  368. package/src/plugins/builtin/chat/controller/index.ts +68 -17
  369. package/src/plugins/builtin/chat/controller/mention-candidates.ts +104 -0
  370. package/src/plugins/builtin/chat/controller/realtime.ts +9 -0
  371. package/src/plugins/builtin/chat/controller/state.ts +10 -0
  372. package/src/plugins/builtin/chat/controller/view.ts +2 -0
  373. package/src/plugins/builtin/chat/conversation-recency.ts +73 -0
  374. package/src/plugins/builtin/chat/conversations.ts +12 -5
  375. package/src/plugins/builtin/chat/ghost-user.ts +11 -3
  376. package/src/plugins/builtin/chat/layout.ts +25 -5
  377. package/src/plugins/builtin/chat/message/desktop.tsx +15 -5
  378. package/src/plugins/builtin/chat/message/header.tsx +26 -4
  379. package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
  380. package/src/plugins/builtin/chat/message/render-state.ts +28 -1
  381. package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
  382. package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
  383. package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
  384. package/src/plugins/builtin/chat/share/flow.tsx +9 -73
  385. package/src/plugins/builtin/chat/sidebar-rows.ts +18 -5
  386. package/src/plugins/builtin/chat/sidebar.tsx +6 -1
  387. package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
  388. package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
  389. package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
  390. package/src/plugins/builtin/cloud/askg/manifest.ts +4 -3
  391. package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
  392. package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
  393. package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
  394. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
  395. package/src/plugins/builtin/cloud/plugin.tsx +2 -0
  396. package/src/plugins/builtin/cloud/team/module.tsx +5 -1
  397. package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
  398. package/src/plugins/builtin/cloud/team/views.ts +11 -4
  399. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
  400. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +16 -5
  401. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
  402. package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
  403. package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
  404. package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
  405. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
  406. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
  407. package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
  408. package/src/plugins/builtin/commodities-energy/index.tsx +31 -9
  409. package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
  410. package/src/plugins/builtin/commodity-balances/client.ts +51 -193
  411. package/src/plugins/builtin/commodity-balances/headless.ts +10 -3
  412. package/src/plugins/builtin/commodity-balances/model.ts +5 -180
  413. package/src/plugins/builtin/commodity-balances/pane.tsx +3 -0
  414. package/src/plugins/builtin/company-attention/headless.ts +15 -7
  415. package/src/plugins/builtin/company-attention/index.tsx +1 -1
  416. package/src/plugins/builtin/company-attention/model.ts +49 -4
  417. package/src/plugins/builtin/company-attention/pane.tsx +11 -9
  418. package/src/plugins/builtin/company-kpis/headless.ts +4 -3
  419. package/src/plugins/builtin/company-kpis/index.tsx +2 -2
  420. package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
  421. package/src/plugins/builtin/congress-trades/headless.ts +23 -2
  422. package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
  423. package/src/plugins/builtin/cot/headless.ts +5 -2
  424. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
  425. package/src/plugins/builtin/credit-boards/client.ts +9 -2
  426. package/src/plugins/builtin/credit-boards/headless.ts +93 -27
  427. package/src/plugins/builtin/credit-boards/index.tsx +15 -4
  428. package/src/plugins/builtin/credit-boards/model.ts +105 -6
  429. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
  430. package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
  431. package/src/plugins/builtin/credit-documents/index.tsx +3 -0
  432. package/src/plugins/builtin/credit-documents/model.ts +3 -10
  433. package/src/plugins/builtin/crypto-board/client.ts +152 -2
  434. package/src/plugins/builtin/crypto-board/headless.ts +138 -19
  435. package/src/plugins/builtin/crypto-board/index.tsx +5 -3
  436. package/src/plugins/builtin/crypto-board/model.ts +210 -12
  437. package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
  438. package/src/plugins/builtin/crypto-board/series.ts +52 -1
  439. package/src/plugins/builtin/crypto-board/supply.ts +123 -0
  440. package/src/plugins/builtin/custom-view/index.tsx +1 -1
  441. package/src/plugins/builtin/custom-view/loader.ts +57 -7
  442. package/src/plugins/builtin/custom-view/sources.ts +146 -0
  443. package/src/plugins/builtin/custom-view/view-spec.ts +37 -1
  444. package/src/plugins/builtin/debt-maturities/client.ts +54 -1
  445. package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
  446. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  447. package/src/plugins/builtin/debt-maturities/model.ts +58 -13
  448. package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
  449. package/src/plugins/builtin/dividend-yield/client.ts +42 -36
  450. package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
  451. package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
  452. package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
  453. package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
  454. package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
  455. package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
  456. package/src/plugins/builtin/dividend-yield/types.ts +6 -1
  457. package/src/plugins/builtin/dividend-yield/view.ts +1 -1
  458. package/src/plugins/builtin/docs/blocks.tsx +54 -8
  459. package/src/plugins/builtin/docs/pane.tsx +8 -13
  460. package/src/plugins/builtin/earnings/board-model.ts +33 -3
  461. package/src/plugins/builtin/earnings/board-table.ts +59 -14
  462. package/src/plugins/builtin/earnings/board.tsx +36 -3
  463. package/src/plugins/builtin/earnings/headless.ts +27 -7
  464. package/src/plugins/builtin/earnings/history-model.ts +9 -1
  465. package/src/plugins/builtin/earnings/history-table.ts +16 -5
  466. package/src/plugins/builtin/earnings/history.tsx +40 -10
  467. package/src/plugins/builtin/earnings/index.tsx +3 -1
  468. package/src/plugins/builtin/earnings/no-earnings.ts +52 -0
  469. package/src/plugins/builtin/earnings-calls/data.ts +51 -0
  470. package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
  471. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  472. package/src/plugins/builtin/earnings-calls/model.ts +97 -0
  473. package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
  474. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
  475. package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
  476. package/src/plugins/builtin/econ/calendar-model.ts +22 -0
  477. package/src/plugins/builtin/econ/calendar-source.ts +35 -0
  478. package/src/plugins/builtin/econ/index.tsx +40 -8
  479. package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
  480. package/src/plugins/builtin/econ-statistics/detail.tsx +11 -1
  481. package/src/plugins/builtin/econ-statistics/headless.ts +31 -5
  482. package/src/plugins/builtin/econ-statistics/pane.tsx +5 -3
  483. package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
  484. package/src/plugins/builtin/econ-statistics/view.ts +23 -0
  485. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  486. package/src/plugins/builtin/equity-screener/model.ts +46 -4
  487. package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
  488. package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
  489. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  490. package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
  491. package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
  492. package/src/plugins/builtin/executives/index.tsx +1 -0
  493. package/src/plugins/builtin/exposure/editor.tsx +3 -3
  494. package/src/plugins/builtin/fear-greed/index.tsx +9 -0
  495. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  496. package/src/plugins/builtin/futures/index.tsx +2 -2
  497. package/src/plugins/builtin/futures/model.ts +39 -25
  498. package/src/plugins/builtin/futures/series.ts +38 -1
  499. package/src/plugins/builtin/futures/table.tsx +1 -1
  500. package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
  501. package/src/plugins/builtin/futures-curve/client.ts +4 -4
  502. package/src/plugins/builtin/futures-curve/headless.ts +24 -4
  503. package/src/plugins/builtin/futures-curve/index.tsx +2 -2
  504. package/src/plugins/builtin/futures-curve/model.ts +50 -9
  505. package/src/plugins/builtin/futures-curve/pane.tsx +14 -10
  506. package/src/plugins/builtin/help/index.tsx +55 -8
  507. package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
  508. package/src/plugins/builtin/holders/headless.ts +12 -0
  509. package/src/plugins/builtin/insider/headless.ts +345 -5
  510. package/src/plugins/builtin/insider/index.tsx +304 -36
  511. package/src/plugins/builtin/insider/insiders.tsx +224 -0
  512. package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
  513. package/src/plugins/builtin/insider/signals-client.ts +193 -0
  514. package/src/plugins/builtin/insider/signals-model.ts +718 -0
  515. package/src/plugins/builtin/insider/signals.tsx +376 -0
  516. package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
  517. package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
  518. package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
  519. package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
  520. package/src/plugins/builtin/iv-history/client.ts +41 -2
  521. package/src/plugins/builtin/iv-history/headless.ts +26 -16
  522. package/src/plugins/builtin/iv-history/screen-pane.tsx +25 -7
  523. package/src/plugins/builtin/jobs/headless.ts +1 -0
  524. package/src/plugins/builtin/jobs/index.tsx +1 -0
  525. package/src/plugins/builtin/jodi/client.ts +42 -205
  526. package/src/plugins/builtin/jodi/headless.ts +15 -4
  527. package/src/plugins/builtin/jodi/model.ts +18 -43
  528. package/src/plugins/builtin/jodi/pane.tsx +5 -0
  529. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  530. package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
  531. package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
  532. package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
  533. package/src/plugins/builtin/market-movers/client.ts +32 -6
  534. package/src/plugins/builtin/market-movers/headless.ts +7 -2
  535. package/src/plugins/builtin/market-movers/model.ts +64 -3
  536. package/src/plugins/builtin/market-movers/screener.ts +20 -9
  537. package/src/plugins/builtin/market-valuation/detail.tsx +7 -2
  538. package/src/plugins/builtin/market-valuation/headless.ts +17 -4
  539. package/src/plugins/builtin/market-valuation/pane.tsx +8 -4
  540. package/src/plugins/builtin/market-valuation/view.ts +10 -0
  541. package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
  542. package/src/plugins/builtin/mna/distress/headless.ts +2 -1
  543. package/src/plugins/builtin/mna/headless.ts +14 -2
  544. package/src/plugins/builtin/mna/index.tsx +1 -0
  545. package/src/plugins/builtin/news/headless.ts +4 -0
  546. package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
  547. package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
  548. package/src/plugins/builtin/notes/cli.ts +8 -4
  549. package/src/plugins/builtin/notes/files.ts +66 -20
  550. package/src/plugins/builtin/notes/migration.ts +18 -6
  551. package/src/plugins/builtin/notes/owner.tsx +3 -2
  552. package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
  553. package/src/plugins/builtin/options-positioning/client.ts +10 -0
  554. package/src/plugins/builtin/options-positioning/headless.ts +88 -13
  555. package/src/plugins/builtin/options-positioning/index.tsx +2 -2
  556. package/src/plugins/builtin/options-positioning/model.ts +33 -0
  557. package/src/plugins/builtin/options-positioning/pane.tsx +38 -16
  558. package/src/plugins/builtin/options-scenario/charts.tsx +13 -4
  559. package/src/plugins/builtin/options-scenario/client.ts +114 -17
  560. package/src/plugins/builtin/options-scenario/collar.ts +141 -0
  561. package/src/plugins/builtin/options-scenario/csp.ts +1 -1
  562. package/src/plugins/builtin/options-scenario/freshness.ts +27 -0
  563. package/src/plugins/builtin/options-scenario/headless.ts +30 -12
  564. package/src/plugins/builtin/options-scenario/index.tsx +1 -1
  565. package/src/plugins/builtin/options-scenario/model.ts +55 -5
  566. package/src/plugins/builtin/options-scenario/pane.tsx +24 -5
  567. package/src/plugins/builtin/pe-band/index.tsx +1 -1
  568. package/src/plugins/builtin/pe-band/model.ts +1 -15
  569. package/src/plugins/builtin/perps/headless.ts +30 -13
  570. package/src/plugins/builtin/perps/model.ts +45 -3
  571. package/src/plugins/builtin/perps/pane.tsx +7 -7
  572. package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
  573. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
  574. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +144 -63
  575. package/src/plugins/builtin/portfolio-list/cli/render.ts +373 -48
  576. package/src/plugins/builtin/portfolio-list/cli/shared.ts +23 -9
  577. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +25 -35
  578. package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
  579. package/src/plugins/builtin/portfolio-list/headless.ts +161 -32
  580. package/src/plugins/builtin/portfolio-list/income.ts +296 -0
  581. package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
  582. package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
  583. package/src/plugins/builtin/portfolio-list/pane/index.tsx +63 -14
  584. package/src/plugins/builtin/portfolio-list/pane/remove-ticker.ts +1 -1
  585. package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
  586. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +38 -8
  587. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +12 -4
  588. package/src/plugins/builtin/portfolio-list/settings.ts +22 -0
  589. package/src/plugins/builtin/portfolio-list/since-last-seen.ts +197 -0
  590. package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
  591. package/src/plugins/builtin/portfolio-list/summary/totals.ts +32 -4
  592. package/src/plugins/builtin/portfolio-list/table.tsx +39 -7
  593. package/src/plugins/builtin/power/prices-headless.ts +2 -1
  594. package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
  595. package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
  596. package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
  597. package/src/plugins/builtin/realized-vol/headless.ts +6 -4
  598. package/src/plugins/builtin/realized-vol/model.ts +5 -1
  599. package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
  600. package/src/plugins/builtin/realized-vol/settings.ts +1 -1
  601. package/src/plugins/builtin/research/analyst-headless.ts +4 -0
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +16 -5
  603. package/src/plugins/builtin/research/event-model.ts +63 -51
  604. package/src/plugins/builtin/research/headless-schema.ts +1 -0
  605. package/src/plugins/builtin/research/headless.ts +4 -1
  606. package/src/plugins/builtin/research/index.tsx +3 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
  608. package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
  609. package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
  610. package/src/plugins/builtin/reverse-dcf/headless.ts +28 -9
  611. package/src/plugins/builtin/reverse-dcf/index.tsx +5 -2
  612. package/src/plugins/builtin/reverse-dcf/model.ts +87 -6
  613. package/src/plugins/builtin/reverse-dcf/pane.tsx +30 -7
  614. package/src/plugins/builtin/risk-factors/headless.ts +7 -0
  615. package/src/plugins/builtin/risk-factors/index.tsx +1 -0
  616. package/src/plugins/builtin/scanner/feed.ts +5 -3
  617. package/src/plugins/builtin/scanner/headless.ts +9 -57
  618. package/src/plugins/builtin/scanner/index.ts +1 -2
  619. package/src/plugins/builtin/sec/forms.ts +2 -6
  620. package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
  621. package/src/plugins/builtin/sec/fund-facts.ts +328 -0
  622. package/src/plugins/builtin/sec/headless.ts +140 -44
  623. package/src/plugins/builtin/sec/index.tsx +95 -30
  624. package/src/plugins/builtin/sec/model.ts +2 -44
  625. package/src/plugins/builtin/shared/earnings-report.ts +48 -1
  626. package/src/plugins/builtin/shared/headless-options.ts +10 -0
  627. package/src/plugins/builtin/shared/history-span.ts +55 -0
  628. package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
  629. package/src/plugins/builtin/shared/move-rank.ts +108 -0
  630. package/src/plugins/builtin/shared/report-freshness.ts +45 -20
  631. package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
  632. package/src/plugins/builtin/shared/series-detail-chart.tsx +5 -2
  633. package/src/plugins/builtin/shared/series-list-detail.tsx +7 -3
  634. package/src/plugins/builtin/shared/ticker-surface.ts +16 -2
  635. package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
  636. package/src/plugins/builtin/shared/use-quote-board.ts +13 -5
  637. package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
  638. package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
  639. package/src/plugins/builtin/short-interest/headless.ts +3 -0
  640. package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
  641. package/src/plugins/builtin/social-mentions/client.ts +8 -1
  642. package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
  643. package/src/plugins/builtin/supply-chain/client.ts +12 -3
  644. package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
  645. package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
  646. package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
  647. package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
  648. package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
  649. package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
  650. package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
  651. package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
  652. package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
  653. package/src/plugins/builtin/supply-chain/headless.ts +69 -27
  654. package/src/plugins/builtin/supply-chain/index.tsx +1 -1
  655. package/src/plugins/builtin/supply-chain/model.ts +76 -15
  656. package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
  657. package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
  658. package/src/plugins/builtin/themes/headless.ts +15 -2
  659. package/src/plugins/builtin/themes/model.ts +2 -5
  660. package/src/plugins/builtin/thirteenf/api.ts +50 -2
  661. package/src/plugins/builtin/thirteenf/data.ts +250 -11
  662. package/src/plugins/builtin/thirteenf/headless.ts +311 -28
  663. package/src/plugins/builtin/thirteenf/index.tsx +4 -1
  664. package/src/plugins/builtin/thirteenf/model.ts +244 -19
  665. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
  666. package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
  667. package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
  668. package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
  669. package/src/plugins/builtin/thirteenf/types.ts +49 -0
  670. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +106 -24
  671. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +108 -0
  672. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +26 -8
  673. package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
  674. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
  675. package/src/plugins/builtin/ticker-detail/headless-schema.ts +4 -2
  676. package/src/plugins/builtin/ticker-detail/headless.ts +109 -23
  677. package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
  678. package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
  679. package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
  680. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
  681. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +37 -4
  682. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
  683. package/src/plugins/builtin/time-sales/client.ts +7 -4
  684. package/src/plugins/builtin/time-sales/headless.ts +71 -22
  685. package/src/plugins/builtin/time-sales/model.ts +12 -0
  686. package/src/plugins/builtin/time-sales/pane.tsx +31 -7
  687. package/src/plugins/builtin/time-sales/window.ts +128 -0
  688. package/src/plugins/builtin/trace-bonds/client.ts +351 -33
  689. package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
  690. package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
  691. package/src/plugins/builtin/trace-bonds/model.ts +27 -25
  692. package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
  693. package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
  694. package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
  695. package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
  696. package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
  697. package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
  698. package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
  699. package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
  700. package/src/plugins/builtin/vol-surface/headless.ts +3 -2
  701. package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
  702. package/src/plugins/builtin/vol-surface/stored.ts +4 -7
  703. package/src/plugins/builtin/volatility/chart-model.ts +16 -15
  704. package/src/plugins/builtin/volatility/charts.tsx +5 -5
  705. package/src/plugins/builtin/volatility/client.ts +73 -2
  706. package/src/plugins/builtin/volatility/evidence.ts +13 -14
  707. package/src/plugins/builtin/volatility/headless.ts +13 -7
  708. package/src/plugins/builtin/volatility/index.tsx +1 -1
  709. package/src/plugins/builtin/volatility/model.ts +104 -38
  710. package/src/plugins/builtin/volatility/pane.tsx +42 -24
  711. package/src/plugins/builtin/volatility/series.ts +22 -13
  712. package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
  713. package/src/plugins/builtin/world-venue-map/headless.ts +25 -8
  714. package/src/plugins/builtin/world-venue-map/index.ts +16 -2
  715. package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
  716. package/src/plugins/builtin/yield-curve/curves.ts +29 -5
  717. package/src/plugins/builtin/yield-curve/headless.ts +41 -8
  718. package/src/plugins/builtin/yield-curve/history.ts +5 -5
  719. package/src/plugins/builtin/yield-curve/index.tsx +30 -13
  720. package/src/plugins/compat.ts +3 -1
  721. package/src/plugins/dependencies.ts +8 -2
  722. package/src/plugins/host-link.ts +12 -5
  723. package/src/plugins/installer.ts +16 -7
  724. package/src/plugins/loader.ts +9 -2
  725. package/src/plugins/marketplace/activation.ts +10 -4
  726. package/src/plugins/registry/host-actions.ts +3 -0
  727. package/src/plugins/registry/index.ts +3 -1
  728. package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +82 -15
  729. package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +143 -55
  730. package/src/portfolio/futures-positions.ts +213 -0
  731. package/src/portfolio/futures-terms.ts +75 -0
  732. package/src/portfolio/manual-lots.ts +78 -0
  733. package/src/{plugins/builtin/portfolio-list → portfolio}/mutations.ts +59 -15
  734. package/src/portfolio/position-metrics.ts +44 -10
  735. package/src/portfolio/valuation-basis.ts +34 -24
  736. package/src/public/__snapshots__/public-api.test.ts.snap +6 -0
  737. package/src/public/time-series.ts +2 -1
  738. package/src/remote/confirm-change.tsx +2 -1
  739. package/src/remote/controller.ts +27 -7
  740. package/src/remote/schema.ts +25 -9
  741. package/src/remote/server.ts +1 -1
  742. package/src/remote/watchlist.ts +9 -1
  743. package/src/renderers/cloudflare/http-proxy.ts +21 -13
  744. package/src/renderers/dom/data-table/row.tsx +1 -1
  745. package/src/renderers/dom/desktop/audio-player.tsx +312 -0
  746. package/src/renderers/dom/desktop/control-styles.ts +17 -82
  747. package/src/renderers/dom/desktop/controls.tsx +39 -63
  748. package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
  749. package/src/renderers/dom/desktop/icons.tsx +8 -0
  750. package/src/renderers/dom/desktop/list-view.tsx +6 -6
  751. package/src/renderers/dom/desktop/popover.tsx +0 -3
  752. package/src/renderers/dom/desktop/query-bar.tsx +7 -5
  753. package/src/renderers/dom/desktop/select-field.tsx +9 -8
  754. package/src/renderers/dom/desktop/stack-header.ts +3 -0
  755. package/src/renderers/dom/dom-ui-host.tsx +5 -2
  756. package/src/renderers/dom/host/chart-surface.tsx +3 -3
  757. package/src/renderers/dom/host/size-observer.ts +33 -4
  758. package/src/renderers/dom/host/surface-3d.tsx +3 -2
  759. package/src/renderers/dom/host/surface-fit.ts +4 -1
  760. package/src/renderers/dom/host/tabs.tsx +22 -132
  761. package/src/renderers/dom/styles.css +358 -160
  762. package/src/renderers/dom/windowed-list.tsx +201 -0
  763. package/src/renderers/dom/windowed-rows.ts +65 -0
  764. package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
  765. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +2 -9
  766. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
  767. package/src/renderers/electrobun/bun/desktop/http-stream.ts +21 -6
  768. package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
  769. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
  770. package/src/renderers/electrobun/bun/desktop/update.ts +21 -6
  771. package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
  772. package/src/renderers/electrobun/shared/protocol.ts +4 -2
  773. package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
  774. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
  775. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  776. package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
  777. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
  778. package/src/renderers/electrobun/view/http-fetch.ts +12 -1
  779. package/src/series/capability.ts +1 -0
  780. package/src/series/files.ts +9 -3
  781. package/src/series/registry.ts +40 -14
  782. package/src/series/resolve.ts +121 -18
  783. package/src/series/standalone.ts +3 -2
  784. package/src/series/types.ts +55 -1
  785. package/src/series/validate.ts +39 -0
  786. package/src/shares/api.ts +26 -7
  787. package/src/shares/bug-report-dialog.tsx +2 -2
  788. package/src/shares/bug-report-flow.tsx +4 -7
  789. package/src/shares/capture-flow.ts +5 -4
  790. package/src/shares/capture-preview.tsx +2 -2
  791. package/src/shares/chat.ts +7 -27
  792. package/src/shares/flow.tsx +86 -40
  793. package/src/shares/location.ts +1 -3
  794. package/src/shares/pane-image.ts +11 -9
  795. package/src/shares/pane.ts +5 -2
  796. package/src/shares/payload.ts +1 -1
  797. package/src/shares/personal-pane.ts +3 -3
  798. package/src/shares/portable-layout.ts +9 -2
  799. package/src/shares/ready.ts +42 -0
  800. package/src/shares/test-harness.ts +62 -0
  801. package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
  802. package/src/sources/gloomberb-cloud/index.ts +64 -12
  803. package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
  804. package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
  805. package/src/sources/history-omitted.ts +34 -0
  806. package/src/sources/history-result.ts +3 -0
  807. package/src/sources/history-retention.ts +1 -1
  808. package/src/sources/listing-symbols.ts +8 -4
  809. package/src/sources/provider-errors.ts +43 -1
  810. package/src/sources/provider-router/batches.ts +3 -2
  811. package/src/sources/provider-router/cache.ts +2 -1
  812. package/src/sources/provider-router/cached-routes.ts +9 -3
  813. package/src/sources/provider-router/history.ts +9 -8
  814. package/src/sources/provider-router/index.ts +18 -3
  815. package/src/sources/provider-router/primary.ts +5 -4
  816. package/src/sources/provider-router/quote-route.ts +3 -1
  817. package/src/sources/provider-router/routing.ts +2 -1
  818. package/src/sources/provider-router/search.ts +47 -13
  819. package/src/sources/provider-router/streaming.ts +7 -4
  820. package/src/sources/sec-edgar.ts +1 -3
  821. package/src/state/app/context/index.tsx +9 -0
  822. package/src/state/app/tab-cursor.ts +222 -0
  823. package/src/state/hooks/quote-streaming.ts +3 -2
  824. package/src/state/hooks/session-snapshot.ts +3 -2
  825. package/src/state/persist-scheduler.ts +12 -4
  826. package/src/sync/controller.ts +22 -1
  827. package/src/sync/core-contributors.ts +264 -74
  828. package/src/team/collections-sync.ts +14 -4
  829. package/src/team/collections.ts +40 -11
  830. package/src/team/store.ts +5 -4
  831. package/src/telemetry/attention-counts.ts +8 -2
  832. package/src/telemetry/crash-reports-dom.ts +3 -0
  833. package/src/telemetry/crash-reports-node.ts +7 -4
  834. package/src/telemetry/crash-reports.ts +11 -11
  835. package/src/telemetry/usage-counts.ts +16 -12
  836. package/src/test-support/config-store.ts +31 -0
  837. package/src/test-support/moved-symbols.ts +64 -0
  838. package/src/theme/colors.ts +32 -0
  839. package/src/theme/font-scale.ts +2 -0
  840. package/src/theme/ui-tokens.ts +71 -0
  841. package/src/tickers/batched-lookups.ts +186 -0
  842. package/src/tickers/company-name-listing.ts +97 -0
  843. package/src/tickers/company-name.ts +13 -0
  844. package/src/tickers/instrument-coverage.ts +112 -0
  845. package/src/tickers/listing-fate.ts +282 -0
  846. package/src/tickers/listing-venues.ts +24 -5
  847. package/src/tickers/open-target.ts +13 -5
  848. package/src/tickers/search/index.ts +156 -37
  849. package/src/tickers/search/ranking.ts +68 -3
  850. package/src/tickers/search/types.ts +3 -0
  851. package/src/tickers/search/upsert.ts +22 -7
  852. package/src/tickers/terminal-codes.ts +79 -0
  853. package/src/tickers/ticker-changes.ts +100 -12
  854. package/src/tickers/us-listing.ts +2 -1
  855. package/src/time-series/bar-spacing.ts +19 -0
  856. package/src/time-series/chart-data.ts +116 -21
  857. package/src/time-series/field-catalog.ts +5 -2
  858. package/src/time-series/forward-valuation.ts +10 -7
  859. package/src/time-series/fundamentals.ts +103 -17
  860. package/src/time-series/hooks.ts +2 -0
  861. package/src/time-series/ice-credit.ts +17 -2
  862. package/src/time-series/live-bars.ts +24 -9
  863. package/src/time-series/live-quotes.ts +2 -3
  864. package/src/time-series/parsed-history-cache.ts +2 -0
  865. package/src/time-series/price-comparison.ts +6 -1
  866. package/src/time-series/price-units.ts +69 -0
  867. package/src/time-series/resolve.ts +114 -14
  868. package/src/time-series/session-bar.ts +138 -0
  869. package/src/time-series/spec.ts +14 -4
  870. package/src/time-series/studies.ts +214 -15
  871. package/src/time-series/transforms.ts +2 -0
  872. package/src/time-series/types.ts +33 -1
  873. package/src/time-series/use-chart-resolution.ts +2 -1
  874. package/src/time-series/valuation-price.ts +13 -0
  875. package/src/types/config.ts +17 -1
  876. package/src/types/data-provider.ts +20 -0
  877. package/src/types/financials.ts +2 -0
  878. package/src/types/headless.ts +169 -1
  879. package/src/types/instrument.ts +6 -0
  880. package/src/types/plugin.ts +39 -9
  881. package/src/types/price-history.ts +5 -0
  882. package/src/types/ticker-changes.ts +19 -0
  883. package/src/types/ticker.ts +10 -2
  884. package/src/ui/context-menu.tsx +2 -0
  885. package/src/ui/host.tsx +45 -4
  886. package/src/ui/measured-cells.ts +13 -7
  887. package/src/ui/qr.ts +7 -5
  888. package/src/updater/index.ts +8 -6
  889. package/src/utils/asset-category.ts +20 -0
  890. package/src/utils/calendar-date.ts +86 -27
  891. package/src/utils/currency-units.ts +17 -0
  892. package/src/utils/debug-log.ts +1 -1
  893. package/src/utils/decimal-comma.ts +83 -3
  894. package/src/utils/dividend-cash.ts +48 -0
  895. package/src/utils/dom-screenshot-rasters.ts +3 -1
  896. package/src/utils/dom-screenshot.ts +14 -10
  897. package/src/utils/exchange-rate-snapshot.ts +9 -4
  898. package/src/utils/external-url.ts +1 -0
  899. package/src/utils/fiscal-period.ts +47 -0
  900. package/src/utils/format.ts +5 -2
  901. package/src/utils/forward-dividend.ts +160 -11
  902. package/src/utils/fundamentals.ts +7 -2
  903. package/src/utils/futures-generic.ts +34 -8
  904. package/src/utils/http-proxy-response.ts +67 -9
  905. package/src/utils/local-utc-offset.ts +2 -0
  906. package/src/utils/log-failure.ts +31 -0
  907. package/src/utils/option-expiry.ts +12 -12
  908. package/src/utils/plugin-proxy-hosts.json +1 -5
  909. package/src/utils/price-history-integrity.ts +56 -0
  910. package/src/utils/price-history.ts +13 -1
  911. package/src/utils/sec-filings.ts +245 -0
  912. package/src/utils/selection-clipboard.ts +5 -2
  913. package/src/utils/throttled-fetch.ts +1 -0
  914. package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
  915. package/src/utils/typo-distance.ts +22 -0
  916. package/src/utils/url.ts +1 -0
  917. package/src/utils/utc-time.ts +11 -0
  918. package/src/plugins/builtin/chat/share/targets.ts +0 -27
  919. package/src/plugins/builtin/shared/zip-text.ts +0 -46
  920. package/src/renderers/dom/host/top-surface.ts +0 -119
  921. package/src/shares/dialog.tsx +0 -221
  922. package/src/shares/live.ts +0 -19
@@ -0,0 +1,75 @@
1
+ import type { ReactNode } from "react";
2
+ import { useThemeColors } from "../../theme/theme-context";
3
+ import { Box, useUiCapabilities } from "../../ui";
4
+
5
+ export interface CardProps {
6
+ children?: ReactNode;
7
+ /**
8
+ * A colour the card belongs to (a relationship's role, a series): a 2px
9
+ * rule down its left edge and the raised fill tinted toward it.
10
+ */
11
+ accent?: string;
12
+ /** Width in cells (terminal) or any Box width. */
13
+ width?: number | `${number}%`;
14
+ /** The card is the chosen one: an accent border. */
15
+ selected?: boolean;
16
+ /** Makes the whole card a control: it takes the hover fill and the pointer. */
17
+ onPress?: () => void;
18
+ }
19
+
20
+ /**
21
+ * The card's look on the desktop and the web, for a card that has to be its
22
+ * own positioned box (a node in a diagram): the same surface Card draws.
23
+ */
24
+ export function cardSurfaceStyle({ selected = false, accent, padding = "var(--gloom-space-sm)" }: {
25
+ selected?: boolean;
26
+ accent?: string;
27
+ /** A card laid out in rows of its own (a diagram node) keeps them: "0 var(--gloom-space-sm)". */
28
+ padding?: string;
29
+ } = {}) {
30
+ return {
31
+ background: accent ? `color-mix(in srgb, var(--gloom-surface-raised) 88%, ${accent})` : "var(--gloom-surface-raised)",
32
+ // The frame is drawn inside the box, so a card keeps the size it was given.
33
+ boxShadow: `inset 0 0 0 1px ${selected ? "var(--gloom-accent)" : "var(--gloom-hairline)"}`,
34
+ ...(accent ? { borderLeft: `${CARD_ACCENT_RULE} solid ${accent}` } : {}),
35
+ borderRadius: "var(--gloom-radius-md)",
36
+ padding,
37
+ boxSizing: "border-box",
38
+ } as const;
39
+ }
40
+
41
+ /** The accent rule of a card or a quote: one width for every rule that says what a block belongs to. */
42
+ export const CARD_ACCENT_RULE = "2px";
43
+
44
+ /**
45
+ * A raised box of related content (a quote tile, a flow step). On the desktop
46
+ * and the web: the raised surface, a 1px hairline, the control radius and the
47
+ * pane's 8px inside; chosen, an accent border. The terminal draws a single
48
+ * line frame. Use it for content that is a unit of its own; rows, tables and
49
+ * key-value rows never need one.
50
+ */
51
+ export function Card({ children, width, selected = false, accent, onPress }: CardProps) {
52
+ const colors = useThemeColors();
53
+ const { nativePaneChrome } = useUiCapabilities();
54
+ if (!nativePaneChrome) {
55
+ return (
56
+ <Box flexDirection="column" width={width} border borderStyle="single" borderColor={selected ? colors.borderFocused : colors.border} onMouseDown={onPress}>
57
+ {children}
58
+ </Box>
59
+ );
60
+ }
61
+ return (
62
+ <Box
63
+ flexDirection="column"
64
+ width={width}
65
+ onMouseDown={onPress}
66
+ data-gloom-ui="card"
67
+ data-gloom-interactive={onPress ? "true" : undefined}
68
+ hoverBackgroundColor={onPress ? "color-mix(in srgb, var(--gloom-surface-raised) 92%, var(--gloom-text-bright))" : undefined}
69
+ data-selected={selected ? "true" : undefined}
70
+ style={cardSurfaceStyle({ selected, accent })}
71
+ >
72
+ {children}
73
+ </Box>
74
+ );
75
+ }
@@ -34,7 +34,7 @@ export function DataTable<T, C extends DataTableColumn = DataTableColumn>(
34
34
  if (!paneId || !renderer.saveTextFile) return;
35
35
  return registerPaneTableExporter(paneId, (filename) => renderer.saveTextFile!({
36
36
  name: filename,
37
- text: createDataTableCsv(propsRef.current),
37
+ text: propsRef.current.exportCsv?.() ?? createDataTableCsv(propsRef.current),
38
38
  mimeType: "text/csv;charset=utf-8",
39
39
  }));
40
40
  }, [paneId, renderer]);
@@ -151,7 +151,9 @@ function reportedRows<T, C extends DataTableColumn>(props: DataTableProps<T, C>)
151
151
  ...(typeof cell.value === "number" && Number.isFinite(cell.value) ? { value: cell.value } : {}),
152
152
  };
153
153
  });
154
- return { key: props.getItemKey(item, index), selected, cells: cells.filter((cell) => cell.text.length > 0) };
154
+ // A section header (FUT's sector) is marked, so a count of the table's rows can leave it out.
155
+ return { key: props.getItemKey(item, index), selected, ...(section ? { section: true } : {}),
156
+ cells: cells.filter((cell) => cell.text.length > 0) };
155
157
  });
156
158
  }
157
159
 
@@ -27,7 +27,13 @@ import type {
27
27
  import { resolveDataTableScrollTop } from "../visible-range";
28
28
  import { useFocusOwningPane, useVisibleRangeEmitter } from "../hooks";
29
29
  import { useStableColumns } from "../stable-columns";
30
- import { resolveDataTableVisibleWindow } from "./model";
30
+ import {
31
+ cutColumnText,
32
+ resolveDataTableColumnClips,
33
+ resolveDataTableVisibleWindow,
34
+ reuseDataTableColumnClips,
35
+ type DataTableColumnClip,
36
+ } from "./model";
31
37
 
32
38
  interface DataTableRowPointerTarget<T> {
33
39
  item: T;
@@ -75,6 +81,7 @@ function OpenTuiDataTableRowInner<
75
81
  sectionWidth,
76
82
  selected,
77
83
  selectedTextOverridesCellColor,
84
+ columnClips,
78
85
  }: {
79
86
  /** Only compared by the row memo; see `getRowVersion`. */
80
87
  rowVersion?: unknown;
@@ -105,6 +112,8 @@ function OpenTuiDataTableRowInner<
105
112
  rowContextMenuSurface: boolean;
106
113
  selected: boolean;
107
114
  selectedTextOverridesCellColor: boolean;
115
+ /** How the viewport cuts each column, null when every column shows whole (resolveDataTableColumnClips). */
116
+ columnClips: readonly (DataTableColumnClip | null)[] | null;
108
117
  }) {
109
118
  const sectionHeader = renderSectionHeader?.(item, index) ?? null;
110
119
 
@@ -191,12 +200,20 @@ function OpenTuiDataTableRowInner<
191
200
  }}
192
201
  >
193
202
  {displayColumns.map((column, columnIndex) => {
194
- const cell = renderCell(item, column, index, rowState);
195
203
  const frozen = columnIndex === 0 && frozenColumnOffset !== undefined;
204
+ const clip = columnClips?.[columnIndex] ?? null;
205
+ const cell = renderCell(item, column, index, rowState);
196
206
  const columnStart = columnStarts[columnIndex] ?? 0;
197
207
  const leadGap = tableColumnLeadGap(displayColumns, columnIndex, columnGap);
198
- const inset = !frozen && frozenColumnOffset !== undefined
208
+ const inset = clip ? clip.inset : !frozen && frozenColumnOffset !== undefined
199
209
  ? Math.min(column.width, Math.max(0, frozenColumnOffset + (displayColumns[0]?.width ?? 0) + columnGap - columnStart)) : 0;
210
+ const shownWidth = clip ? clip.width : column.width - inset;
211
+ // Cut text is fitted to what shows; a number the edge cuts stays blank in its own place,
212
+ // and its cell keeps its background and its press.
213
+ const shownText = clip
214
+ ? cutColumnText(cell.text, column.align, column.width, clip, (text, width) => fitTableCellText(text, width, column.align))
215
+ : shownWidth > 0 ? fitTableCellText(cell.text, shownWidth, column.align) : "";
216
+ const contentCut = clip !== null && column.align === "right" && shownText.trim() === "";
200
217
  return (
201
218
  <Box
202
219
  key={column.id}
@@ -222,10 +239,10 @@ function OpenTuiDataTableRowInner<
222
239
  handleRowMouseDown(itemKey, { item, index }, event);
223
240
  }}
224
241
  >
225
- {cell.content !== undefined ? (frozenColumnOffset === undefined ? cell.content : (
242
+ {cell.content !== undefined && !contentCut ? (frozenColumnOffset === undefined && !clip ? cell.content : (
226
243
  <>
227
244
  {frozen && <Text position="absolute" left={0} top={0}>{" ".repeat(column.width + columnGap + horizontalPadding)}</Text>}
228
- <Box marginLeft={frozen ? horizontalPadding : inset} width={Math.max(0, column.width - inset)} overflow="hidden">
245
+ <Box marginLeft={frozen ? horizontalPadding : inset} width={Math.max(0, shownWidth)} overflow="hidden">
229
246
  {cell.content}
230
247
  </Box>
231
248
  </>
@@ -236,7 +253,7 @@ function OpenTuiDataTableRowInner<
236
253
  ? colors.selectedText
237
254
  : cell.color ?? colors.text}
238
255
  >
239
- {`${frozen ? " ".repeat(horizontalPadding) : ""}${" ".repeat(inset)}${inset < column.width ? fitTableCellText(cell.text, column.width - inset, column.align) : ""}${frozen ? " ".repeat(columnGap) : ""}`}
256
+ {`${frozen ? " ".repeat(horizontalPadding) : ""}${" ".repeat(inset)}${shownText}${frozen ? " ".repeat(columnGap) : ""}`}
240
257
  </Text>
241
258
  )}
242
259
  </Box>
@@ -298,10 +315,13 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
298
315
  const appViewport = useViewport();
299
316
  const nativeRenderer = useNativeRenderer();
300
317
  const [scrollVersion, setScrollVersion] = useState(0);
301
- const [frozenColumnOffset, setFrozenColumnOffset] = useState(0);
318
+ // How far the columns are scrolled sideways: a frozen first column moves with
319
+ // it, and a column the viewport cuts is drawn to what shows (resolveDataTableColumnClips).
320
+ const [scrollLeft, setScrollLeft] = useState(0);
321
+ const frozenColumnOffset = scrollLeft;
302
322
  useEffect(() => {
303
- if (freezeFirstColumn) setFrozenColumnOffset(scrollRef.current?.scrollLeft ?? 0);
304
- }, [freezeFirstColumn, scrollRef]);
323
+ setScrollLeft(scrollRef.current?.scrollLeft ?? 0);
324
+ }, [scrollRef]);
305
325
  const lastAppliedScrollRequestRef = useRef<string | null>(null);
306
326
  const controlledScrollTopRef = useRef<number | null>(null);
307
327
  const scrollTop = virtualize ? (scrollRef.current?.scrollTop ?? 0) : 0;
@@ -358,6 +378,22 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
358
378
  () => tableColumnStarts(displayColumns, columnGap),
359
379
  [columnGap, displayColumns],
360
380
  );
381
+ // A scroll step that cuts the columns as the last one did keeps the same
382
+ // array, so the memoized rows skip the render.
383
+ const columnClipsRef = useRef<readonly (DataTableColumnClip | null)[] | null>(null);
384
+ const columnClips = useMemo(
385
+ () => columnClipsRef.current = reuseDataTableColumnClips(columnClipsRef.current, resolveDataTableColumnClips({
386
+ columnGap,
387
+ columnStarts,
388
+ frozenFirstColumn: freezeFirstColumn,
389
+ horizontalPadding,
390
+ scrollLeft,
391
+ // A table that cannot scroll sideways fits its own columns; one it cut could never be scrolled to.
392
+ viewportWidth: showHorizontalScrollbar ? measuredViewportWidth : 0,
393
+ widths: displayColumns.map((column) => column.width),
394
+ })),
395
+ [columnGap, columnStarts, displayColumns, freezeFirstColumn, horizontalPadding, measuredViewportWidth, scrollLeft, showHorizontalScrollbar],
396
+ );
361
397
  const reportVisibleRange = useVisibleRangeEmitter({
362
398
  itemCount: items.length,
363
399
  visibleRangeKey,
@@ -399,8 +435,8 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
399
435
  }, [emitVisibleRange, nativeRenderer, onBodyScrollActivity, scrollRef, virtualize]);
400
436
  const syncHorizontalScroll = useCallback(() => {
401
437
  syncHeaderScroll();
402
- if (freezeFirstColumn) setFrozenColumnOffset(scrollRef.current?.scrollLeft ?? 0);
403
- }, [freezeFirstColumn, scrollRef, syncHeaderScroll]);
438
+ setScrollLeft(scrollRef.current?.scrollLeft ?? 0);
439
+ }, [scrollRef, syncHeaderScroll]);
404
440
  useScrollBoxScrollActivity({
405
441
  scrollRef,
406
442
  onVerticalScroll: handleBodyScrollActivity,
@@ -411,9 +447,9 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
411
447
  const body = scrollRef.current;
412
448
  if (!header || !body || body.scrollLeft === header.scrollLeft) return;
413
449
  body.scrollLeft = header.scrollLeft;
414
- if (freezeFirstColumn) setFrozenColumnOffset(body.scrollLeft ?? 0);
450
+ setScrollLeft(body.scrollLeft ?? 0);
415
451
  nativeRenderer.requestRender();
416
- }, [freezeFirstColumn, headerScrollRef, nativeRenderer, scrollRef]);
452
+ }, [headerScrollRef, nativeRenderer, scrollRef]);
417
453
  useScrollBoxScrollActivity({
418
454
  scrollRef: headerScrollRef,
419
455
  onHorizontalScroll: syncBodyScroll,
@@ -490,6 +526,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
490
526
  }
491
527
  if (!horizontalScrollbarVisible) {
492
528
  body.scrollLeft = 0;
529
+ setScrollLeft(0);
493
530
  }
494
531
  }
495
532
  }, [columns.length, headerScrollRef, horizontalScrollbarVisible, items.length, measuredViewportHeight, scrollRef]);
@@ -565,8 +602,10 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
565
602
  {displayColumns.map((column, columnIndex) => {
566
603
  const frozen = freezeFirstColumn && columnIndex === 0;
567
604
  const columnStart = columnStarts[columnIndex] ?? 0;
568
- const inset = freezeFirstColumn && !frozen
605
+ const clip = columnClips?.[columnIndex] ?? null;
606
+ const inset = clip ? clip.inset : freezeFirstColumn && !frozen
569
607
  ? Math.min(column.width, Math.max(0, frozenColumnOffset + (displayColumns[0]?.width ?? 0) + columnGap - columnStart)) : 0;
608
+ const shownWidth = clip ? clip.width : column.width - inset;
570
609
  const isSorted = sortColumnId === column.id;
571
610
  const marker = sortDirection === "asc" ? "▲" : "▼";
572
611
  // An unlabeled column shows the bare marker, not a stray space before it.
@@ -576,12 +615,13 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
576
615
  // over its numbers.
577
616
  const hasNextLabel = columnIndex < displayColumns.length - 1
578
617
  && tableColumnLeadGap(displayColumns, columnIndex + 1, columnGap) === 0;
579
- const labelText = " ".repeat(inset) + (inset < column.width ? fitTableHeaderText(
580
- column.label + indicator,
581
- column.width - inset,
582
- column.align,
583
- hasNextLabel,
584
- ) : "");
618
+ const label = column.label + indicator;
619
+ const labelText = " ".repeat(inset) + (clip
620
+ // Cut on the right, the label's last cell is the edge.
621
+ ? cutColumnText(label, column.align, column.width, clip, (text, width, cutRight) => (
622
+ fitTableHeaderText(text, width, column.align, hasNextLabel && !cutRight)
623
+ ))
624
+ : shownWidth > 0 ? fitTableHeaderText(label, shownWidth, column.align, hasNextLabel) : "");
585
625
  return (
586
626
  <Box
587
627
  key={column.id}
@@ -667,6 +707,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
667
707
  sectionWidth={sectionWidth}
668
708
  selected={isSelected(item, index)}
669
709
  selectedTextOverridesCellColor={selectedTextOverridesCellColor}
710
+ columnClips={columnClips}
670
711
  />
671
712
  );
672
713
  }),
@@ -1,3 +1,107 @@
1
+ import { displayWidth } from "../../../../utils/format";
2
+
3
+ /**
4
+ * Where the viewport cuts a column: `inset` cells hidden on its left (past the
5
+ * scroll, or under a frozen first column), then `width` cells that show (0
6
+ * when none do). A column whose shown cells stop short of its width is cut on
7
+ * the right as well. `cutColumnText` says what such a column draws.
8
+ */
9
+ export interface DataTableColumnClip {
10
+ inset: number;
11
+ width: number;
12
+ }
13
+
14
+ /** Whether the viewport's edge falls inside the column, not after it. */
15
+ function clipCutsRight(clip: DataTableColumnClip, columnWidth: number): boolean {
16
+ return clip.inset + clip.width < columnWidth;
17
+ }
18
+
19
+ /**
20
+ * What a cut column draws in the cells that show. Text is fitted to them from
21
+ * the visible edge, with an ellipsis when it is longer, so a name reads
22
+ * "Definitive agr\u2026", never a hard stop. A number, right-aligned or
23
+ * centred, keeps its place in the column and shows when those cells hold all
24
+ * of it; otherwise they stay blank, because part of one reads as another
25
+ * number (LAST 98.53 as "98", a header as "LA"). Scrolling brings it whole.
26
+ *
27
+ * `fit` places the text in a width (fitTableCellText or fitTableHeaderText);
28
+ * `cutRight` tells it the width ends at the viewport's edge.
29
+ */
30
+ export function cutColumnText(
31
+ text: string,
32
+ align: string | undefined,
33
+ columnWidth: number,
34
+ clip: DataTableColumnClip,
35
+ fit: (text: string, width: number, cutRight: boolean) => string,
36
+ ): string {
37
+ if (clip.width <= 0) return "";
38
+ if (align !== "right" && align !== "center") return fit(text, clip.width, clipCutsRight(clip, columnWidth));
39
+ const placed = fit(text, columnWidth, false);
40
+ const body = placed.trim();
41
+ const start = placed.length - placed.trimStart().length;
42
+ const end = start + displayWidth(body);
43
+ const shownEnd = clip.inset + clip.width;
44
+ if (!body || start < clip.inset || end > shownEnd) return " ".repeat(clip.width);
45
+ return `${" ".repeat(start - clip.inset)}${body}${" ".repeat(shownEnd - end)}`;
46
+ }
47
+
48
+ function sameClip(a: DataTableColumnClip | null, b: DataTableColumnClip | null): boolean {
49
+ return a === b || (a !== null && b !== null && a.inset === b.inset && a.width === b.width);
50
+ }
51
+
52
+ /**
53
+ * The previous clips when the new ones say the same, so the memoized rows a
54
+ * horizontal scroll did not change keep their props and skip the render.
55
+ */
56
+ export function reuseDataTableColumnClips(
57
+ previous: readonly (DataTableColumnClip | null)[] | null,
58
+ next: (DataTableColumnClip | null)[] | null,
59
+ ): readonly (DataTableColumnClip | null)[] | null {
60
+ if (previous === next || !previous || !next) return next;
61
+ return previous.length === next.length && next.every((clip, index) => sameClip(clip, previous[index] ?? null)) ? previous : next;
62
+ }
63
+
64
+ /**
65
+ * Each column's clip at the current scroll, null for a column shown whole.
66
+ * A frozen first column stays, and what slides under it counts as cut on the
67
+ * left. Null for the whole table when every column is whole or nothing is
68
+ * measured yet.
69
+ */
70
+ export function resolveDataTableColumnClips({
71
+ columnGap,
72
+ columnStarts,
73
+ frozenFirstColumn,
74
+ horizontalPadding,
75
+ scrollLeft,
76
+ viewportWidth,
77
+ widths,
78
+ }: {
79
+ columnGap: number;
80
+ /** Where each column's content starts, from the first column (tableColumnStarts). */
81
+ columnStarts: readonly number[];
82
+ frozenFirstColumn: boolean;
83
+ horizontalPadding: number;
84
+ scrollLeft: number;
85
+ viewportWidth: number;
86
+ /** Each column's drawn width. */
87
+ widths: readonly number[];
88
+ }): (DataTableColumnClip | null)[] | null {
89
+ if (viewportWidth <= 0 || widths.length === 0) return null;
90
+ const right = scrollLeft + viewportWidth;
91
+ const left = frozenFirstColumn ? scrollLeft + horizontalPadding + (widths[0] ?? 0) + columnGap : scrollLeft;
92
+ let cut = false;
93
+ const clips = widths.map((width, index): DataTableColumnClip | null => {
94
+ if (frozenFirstColumn && index === 0) return null;
95
+ const start = horizontalPadding + (columnStarts[index] ?? 0);
96
+ const end = start + width;
97
+ if (start >= left && end <= right) return null;
98
+ cut = true;
99
+ const inset = Math.min(width, Math.max(0, left - start));
100
+ return { inset, width: Math.max(0, Math.min(end, right) - start - inset) };
101
+ });
102
+ return cut ? clips : null;
103
+ }
104
+
1
105
  interface DataTableVisibleWindowOptions<T> {
2
106
  appViewportHeight: number;
3
107
  items: T[];
@@ -14,6 +14,11 @@ export type DataTableColumn = Pick<
14
14
  * automation and screen readers read only `label`.
15
15
  */
16
16
  headerLeading?: ReactNode;
17
+ /**
18
+ * The plain words behind a short label ("Impact" for IMP), shown on hover on
19
+ * the desktop and the web. The terminal has no hover and shows `label` only.
20
+ */
21
+ title?: string;
17
22
  flexGrow?: number;
18
23
  };
19
24
 
@@ -166,6 +171,12 @@ export interface DataTableProps<
166
171
  freezeFirstColumn?: boolean;
167
172
  /** Append export-only source records after the displayed table. */
168
173
  getExportMetadata?: () => readonly (readonly unknown[])[];
174
+ /**
175
+ * What Export CSV writes in place of the rows drawn, for a pane whose
176
+ * export is the data behind its view rather than one table: the backtest
177
+ * writes its daily curve, as `fn BT --csv --equity` prints it.
178
+ */
179
+ exportCsv?: () => string;
169
180
  /**
170
181
  * A rendered-view report (`gloomberb fn`) reads every row, not only those
171
182
  * the viewport shows. For a bounded table a reader needs whole, such as an
@@ -13,7 +13,7 @@ export interface DetailScrollBodyProps {
13
13
  * to the pane footer, and its inset is padding inside what scrolls: text goes
14
14
  * under the footer edge rather than stopping a blank band above it.
15
15
  */
16
- const NATIVE_DETAIL_INSET = { padding: "12px 8px 16px" } as const;
16
+ const NATIVE_DETAIL_INSET = { padding: "var(--gloom-space-md) var(--gloom-inset) var(--gloom-space-lg)" } as const;
17
17
 
18
18
  /**
19
19
  * The scrolling body of a stack detail, filling the space under the stack
@@ -1,7 +1,5 @@
1
1
  import { type ComponentType, type ReactNode } from "react";
2
- import { Box, Text, useUiHost } from "../../ui";
3
- import { t } from "../../i18n";
4
- import { useThemeColors } from "../../theme/theme-context";
2
+ import { Box, useUiHost } from "../../ui";
5
3
  import type { DialogDesktopFooter, DialogKeyHint } from "./frame";
6
4
 
7
5
  export interface DialogActionsProps {
@@ -44,21 +42,3 @@ export interface DialogHintsProps {
44
42
  keys?: DialogKeyHint[];
45
43
  note?: string;
46
44
  }
47
-
48
- /**
49
- * Keys and a note for a dialog that has no button to put them on, such as a
50
- * sign-in code waiting for a phone: keycaps on the desktop and the web, one
51
- * muted line in the terminal.
52
- */
53
- export function DialogHints({ keys = [], note }: DialogHintsProps) {
54
- const colors = useThemeColors();
55
- const HostDialogHints = useUiHost().DialogHints as ComponentType<DialogHintsProps> | undefined;
56
- if (HostDialogHints) return <HostDialogHints keys={keys} note={note} />;
57
- const parts = [...keys.map((hint) => `${hint.key} ${t(hint.label)}`), ...(note ? [t(note)] : [])];
58
- if (parts.length === 0) return null;
59
- return (
60
- <Box height={1}>
61
- <Text fg={colors.textMuted}>{parts.join(" · ")}</Text>
62
- </Box>
63
- );
64
- }
@@ -191,8 +191,15 @@ export interface BadgeProps {
191
191
  variant?: "subtle" | "solid";
192
192
  }
193
193
 
194
- /** A chip as tall as its row runs into the one below in a column of chips; the desktop leaves a hairline above and below, as ticker chips do. */
195
- const NATIVE_BADGE_STYLE = { height: "calc(100% - 4px)", borderRadius: 3 };
194
+ /**
195
+ * The one chip on the desktop: 16px in its 18px row (a chip as tall as its
196
+ * row runs into the one below in a column of chips), the small-mark radius,
197
+ * regular weight. Ticker chips keep bold (ticker/badge).
198
+ */
199
+ export const NATIVE_BADGE_STYLE = { height: "calc(100% - 2px)", borderRadius: "var(--gloom-radius-sm)" };
200
+ /** How far a subtle chip's fill is tinted toward its tone. */
201
+ export const BADGE_TINT = 0.28;
202
+ const NATIVE_BADGE_TEXT_STYLE = { fontWeight: "var(--gloom-weight-regular)" };
196
203
 
197
204
  export function Badge({ label, tone = "neutral", color, variant = "subtle" }: BadgeProps) {
198
205
  const colors = useThemeColors();
@@ -201,9 +208,9 @@ export function Badge({ label, tone = "neutral", color, variant = "subtle" }: Ba
201
208
  const solid = variant === "solid";
202
209
  const neutral = solid && tone === "neutral" && !color;
203
210
  const chip = (
204
- <Box height={nativePaneChrome ? undefined : 1} paddingX={1} backgroundColor={neutral ? colors.selected : solid ? accent : blendHex(colors.bg, accent, 0.28)}
211
+ <Box height={nativePaneChrome ? undefined : 1} paddingX={1} backgroundColor={neutral ? colors.selected : solid ? accent : blendHex(colors.bg, accent, BADGE_TINT)}
205
212
  data-gloom-ui="badge" justifyContent={nativePaneChrome ? "center" : undefined} style={nativePaneChrome ? NATIVE_BADGE_STYLE : undefined}>
206
- <Text fg={neutral ? colors.selectedText : solid ? colors.bg : accent} attributes={TextAttributes.BOLD}>{t(label)}</Text>
213
+ <Text fg={neutral ? colors.selectedText : solid ? colors.bg : accent} attributes={TextAttributes.BOLD} style={nativePaneChrome ? NATIVE_BADGE_TEXT_STYLE : undefined}>{t(label)}</Text>
207
214
  </Box>
208
215
  );
209
216
  return nativePaneChrome ? <Box height={1} flexShrink={0} justifyContent="center">{chip}</Box> : chip;
@@ -228,7 +235,8 @@ export function Divider({ width, height, orientation = "horizontal" }: DividerPr
228
235
  borderColor={colors.border}
229
236
  style={{
230
237
  border: 0,
231
- [vertical ? "borderLeft" : "borderTop"]: `1px solid ${colors.border}`,
238
+ // The one hairline on the desktop; the terminal draws borderColor.
239
+ [vertical ? "borderLeft" : "borderTop"]: "1px solid var(--gloom-hairline)",
232
240
  // A vertical rule given no height runs the height of the row it stands in.
233
241
  ...(vertical && height === undefined ? { height: "auto", alignSelf: "stretch" } : {}),
234
242
  }}
@@ -116,7 +116,7 @@ export function ExternalLinkText(
116
116
  const colors = useThemeColors();
117
117
  const rendererHost = useRendererHost();
118
118
  const { showContextMenu } = useContextMenu();
119
- const { nativeContextMenu } = useUiCapabilities();
119
+ const { nativeContextMenu, nativePaneChrome } = useUiCapabilities();
120
120
  const resolvedOpen = onOpen === openUrl
121
121
  ? (nextUrl: string) => {
122
122
  void rendererHost.openExternal(nextUrl);
@@ -134,11 +134,13 @@ export function ExternalLinkText(
134
134
  usePaneLinkMenuEntry(`link:${url}`, tf("Open {label}", { label: menuLinkLabel(url, label) }), () => resolvedOpen(url));
135
135
  return (
136
136
  <Text
137
- fg={color ?? colors.textBright}
137
+ // Desktop: a link is the text around it, underlined; the pointer brightens it (styles.css).
138
+ fg={color ?? (nativePaneChrome ? "inherit" : colors.textBright)}
138
139
  attributes={TextAttributes.UNDERLINE | attributes}
139
140
  cursor="pointer"
140
141
  style={inline ? INLINE_LINK_STYLE : undefined}
141
142
  role="link"
143
+ data-gloom-link="true"
142
144
  tabIndex={0}
143
145
  wrapText
144
146
  onKeyDown={(event: any) => {
@@ -88,6 +88,18 @@ export interface TextFieldProps {
88
88
  */
89
89
  export const FRAMED_TEXTAREA_DESKTOP_STYLE = { padding: "6px var(--cell-w)", lineHeight: "var(--cell-h)" } as const;
90
90
 
91
+ /**
92
+ * The field look on the desktop and the web (docs/pane-conventions.md, "Design
93
+ * system"): a sunken fill inside the control border, the accent while focused.
94
+ */
95
+ export function fieldFrameStyle(focused: boolean) {
96
+ return {
97
+ border: `1px solid ${focused ? "var(--gloom-accent)" : "var(--gloom-control-border)"}`,
98
+ borderRadius: "var(--gloom-radius-md)",
99
+ backgroundColor: "var(--gloom-surface-sunken)",
100
+ } as const;
101
+ }
102
+
91
103
  const PASSWORD_MASK_CHAR = "*";
92
104
 
93
105
  function maskPassword(value: string): string {
@@ -1,19 +1,21 @@
1
1
  import { useCallback, type ReactNode } from "react";
2
2
  import { priceColor } from "../../theme/colors";
3
3
  import { useThemeColors } from "../../theme/theme-context";
4
+ import { TYPE, WEIGHT } from "../../theme/ui-tokens";
4
5
  import { Text, TextAttributes, useUiCapabilities } from "../../ui";
5
6
  import { displayWidth } from "../../utils/format";
6
7
 
7
8
  /** `value` is a pane's lead figure (a last price); `sub` is the change or detail that rides with it. */
8
9
  export type FigurePart = "value" | "sub";
9
10
 
10
- const FIGURE_FONT_PX: Record<FigurePart, number> = { value: 22, sub: 13 };
11
+ /** On the type scale (src/theme/ui-tokens.ts): the title size for the lead figure, the app's for what rides with it. */
12
+ const FIGURE_FONT_PX: Record<FigurePart, number> = { value: TYPE.title, sub: TYPE.ui };
11
13
  const FIGURE_LINE_HEIGHT: Record<FigurePart, number> = { value: 1.05, sub: 1.1 };
12
14
 
13
15
  // The desktop sets figures larger and heavier than body text; the terminal has one size, so the value is bold.
14
16
  const DESKTOP_FIGURE_STYLE: Record<FigurePart, { fontSize: string; lineHeight: number; fontWeight: number }> = {
15
- value: { fontSize: `${FIGURE_FONT_PX.value}px`, lineHeight: FIGURE_LINE_HEIGHT.value, fontWeight: 700 },
16
- sub: { fontSize: `${FIGURE_FONT_PX.sub}px`, lineHeight: FIGURE_LINE_HEIGHT.sub, fontWeight: 500 },
17
+ value: { fontSize: `${FIGURE_FONT_PX.value}px`, lineHeight: FIGURE_LINE_HEIGHT.value, fontWeight: WEIGHT.bold },
18
+ sub: { fontSize: `${FIGURE_FONT_PX.sub}px`, lineHeight: FIGURE_LINE_HEIGHT.sub, fontWeight: WEIGHT.regular },
17
19
  };
18
20
 
19
21
  function figureLinePx(part: FigurePart): number {
@@ -2,7 +2,8 @@ import { Box, Text, useUiHost } from "../../ui";
2
2
  import { TextAttributes } from "../../ui";
3
3
  import { type ComponentType, type ReactNode } from "react";
4
4
  import { t } from "../../i18n";
5
- import { blendHex, type ThemeColors } from "../../theme/colors";
5
+ import type { ThemeColors } from "../../theme/colors";
6
+ import { RADIUS, SPACE, controlBorderColour, surfaceRaisedColour } from "../../theme/ui-tokens";
6
7
  import { useThemeColors } from "../../theme/theme-context";
7
8
 
8
9
  export interface ModalSurfaceOptions {
@@ -22,16 +23,42 @@ export function modalSurfaceStyle(colors: ThemeColors, options: ModalSurfaceOpti
22
23
  width: options.width ?? "min(540px, 100%)",
23
24
  height: "auto",
24
25
  maxHeight: options.maxHeight ?? "calc(100vh - 88px)",
25
- padding: options.padding ?? 14,
26
- backgroundColor: blendHex(colors.panel, colors.bg, 0.12),
27
- border: `1px solid ${blendHex(colors.border, colors.borderFocused, 0.18)}`,
28
- borderRadius: 6,
29
- boxShadow: `0 18px 48px color-mix(in srgb, ${colors.bg} 46%, transparent), inset 0 1px 0 color-mix(in srgb, ${colors.textBright} 5%, transparent)`,
26
+ padding: options.padding ?? SPACE.lg,
27
+ // The floating surface (docs/pane-conventions.md, "Dialogs, menus and surfaces").
28
+ backgroundColor: surfaceRaisedColour(colors),
29
+ border: `1px solid ${controlBorderColour(colors)}`,
30
+ borderRadius: RADIUS.lg,
31
+ boxShadow: "var(--gloom-elevation)",
30
32
  boxSizing: "border-box" as const,
31
33
  overflowY: "auto" as const,
32
34
  };
33
35
  }
34
36
 
37
+ /**
38
+ * Desktop and web: a small panel that sits on a chart rather than over it (a
39
+ * legend's key): the raised fill, the control border, the surface radius, the
40
+ * app's type, 4px by 8px inside, and no elevation.
41
+ */
42
+ export const FLAT_SURFACE_STYLE = {
43
+ background: "var(--gloom-surface-raised)",
44
+ border: "1px solid var(--gloom-control-border)",
45
+ borderRadius: "var(--gloom-radius-lg)",
46
+ padding: "var(--gloom-space-xs) var(--gloom-space-sm)",
47
+ fontSize: "var(--gloom-type-ui)",
48
+ boxSizing: "border-box",
49
+ } as const;
50
+
51
+ /**
52
+ * Desktop and web: what the pointer is over, explained (a heat map tile, a
53
+ * map feature, a flow's relationship): the flat surface lifted by the one
54
+ * elevation, as everything floating is. A tooltip never takes the pointer.
55
+ */
56
+ export const TOOLTIP_SURFACE_STYLE = {
57
+ ...FLAT_SURFACE_STYLE,
58
+ boxShadow: "var(--gloom-elevation)",
59
+ pointerEvents: "none",
60
+ } as const;
61
+
35
62
  /** A key and what it does, drawn on the desktop and the web as a keycap and a word. */
36
63
  export interface DialogKeyHint {
37
64
  /** As the terminal names it: "Enter", "Esc", "Shift+Enter", "Tab", "↑↓", "y". */
@@ -51,6 +78,13 @@ export interface DialogDesktopFooter {
51
78
  note?: string;
52
79
  }
53
80
 
81
+ /**
82
+ * A form dialog's width, in cells: pane settings and New Portfolio, whose
83
+ * broker connect step fits in it (its QR code, the link, the note wrapped),
84
+ * and the browser sign-in dialogs, which match that step.
85
+ */
86
+ export const FORM_DIALOG_WIDTH = 68;
87
+
54
88
  /**
55
89
  * Desktop and web: the width of a dialog body laid out `columns` cells wide,
56
90
  * narrowed to fit a phone, where the fixed width would run past the edge.
@@ -24,6 +24,8 @@ export type IconName =
24
24
  | "cloud"
25
25
  | "sound-on"
26
26
  | "sound-off"
27
+ | "play"
28
+ | "pause"
27
29
  | "user"
28
30
  | "sort-up"
29
31
  | "sort-down"
@@ -57,6 +59,8 @@ export const ICON_GLYPHS: Record<IconName, string> = {
57
59
  cloud: "☁",
58
60
  "sound-on": "◖)",
59
61
  "sound-off": "◖·",
62
+ play: "▸",
63
+ pause: "‖",
60
64
  user: "@",
61
65
  "sort-up": "▲",
62
66
  "sort-down": "▼",