gloomberb 0.11.2 → 0.12.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.
- package/README.md +7 -4
- package/README.zh-CN.md +4 -2
- package/package.json +28 -1
- package/src/api-client/auth.ts +10 -0
- package/src/api-client/data.ts +108 -1
- package/src/api-client/index.test.ts +127 -0
- package/src/api-client/index.ts +134 -1
- package/src/api-client/normalizers.ts +39 -0
- package/src/api-client/paths.ts +85 -1
- package/src/api-client/types.ts +220 -0
- package/src/app/pane-runtime/index.tsx +15 -12
- package/src/app/pane-runtime/layout-placement.test.ts +27 -0
- package/src/app/pane-runtime/layout-placement.ts +13 -0
- package/src/app/pane-runtime/plugin-bindings.ts +62 -0
- package/src/app.tsx +60 -18
- package/src/architecture/browser-entry-graph.test.ts +96 -0
- package/src/brokers/profile-form.test.ts +25 -27
- package/src/brokers/test-broker.ts +68 -0
- package/src/capabilities/chart-series.ts +3 -2
- package/src/cli/commands/market.ts +2 -2
- package/src/cli/commands/plugins.ts +39 -11
- package/src/cli/desktop-pane-shot.ts +285 -16
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/capabilities.ts +61 -31
- package/src/cli/pane-functions/catalog.ts +16 -4
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/headless.test.ts +247 -0
- package/src/cli/pane-functions/headless.ts +423 -0
- package/src/cli/pane-functions/index.test.ts +9 -0
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +27 -2
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +26 -8
- package/src/cli/pane-functions/screenshot.test.ts +76 -0
- package/src/cli/pane-functions/screenshot.ts +236 -20
- package/src/cli/registry.ts +0 -22
- package/src/cli/restore-plugins.ts +34 -0
- package/src/cli/result.ts +7 -10
- package/src/components/chart/{static/chart → composite}/axis-overlays.test.tsx +3 -3
- package/src/components/chart/{static/chart → composite}/axis-overlays.tsx +6 -11
- package/src/components/chart/{static/chart → composite}/bitmap.ts +17 -3
- package/src/components/chart/composite/composite-chart.test.tsx +68 -20
- package/src/components/chart/composite/composite-chart.tsx +301 -204
- package/src/components/chart/composite/format.ts +8 -2
- package/src/components/chart/composite/interactions.test.ts +68 -102
- package/src/components/chart/composite/interactions.ts +214 -264
- package/src/components/chart/composite/price-axis-labels.test.ts +21 -0
- package/src/components/chart/{price-axis-labels.tsx → composite/price-axis-labels.tsx} +9 -4
- package/src/components/chart/composite/scene.ts +57 -3
- package/src/components/chart/composite/text-renderer.ts +3 -2
- package/src/components/chart/composite/time-scale.ts +138 -57
- package/src/components/chart/composite/types.ts +25 -1
- package/src/components/chart/core/data.ts +9 -13
- package/src/components/chart/core/date-window.ts +7 -1
- package/src/components/chart/core/pointer.ts +3 -0
- package/src/components/chart/core/types.ts +0 -45
- package/src/components/chart/native/chart-rasterizer.ts +0 -1
- package/src/components/chart/native/kitty/index.test.ts +0 -188
- package/src/components/chart/native/raster/crosshair.ts +6 -5
- package/src/components/chart/native/raster/primitives.ts +0 -23
- package/src/components/chart/native/renderer-selection.ts +81 -31
- package/src/components/chart/static/{chart/surface.test.tsx → chart-surface.test.tsx} +28 -80
- package/src/components/chart/static/chart-surface.tsx +150 -0
- package/src/components/chart/static/index.ts +8 -0
- package/src/components/chart/static/multi-line-chart-surface.tsx +51 -166
- package/src/components/chart/static/scatter-chart-surface.test.ts +30 -0
- package/src/components/chart/static/scatter-chart-surface.tsx +135 -34
- package/src/components/chart/static/series.ts +49 -0
- package/src/components/command-bar/action-runtime.ts +1 -3
- package/src/components/command-bar/assist/model.test.ts +17 -2
- package/src/components/command-bar/assist/model.ts +40 -9
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +1 -1
- package/src/components/command-bar/commands/registry.ts +0 -11
- package/src/components/command-bar/helpers.test.ts +2 -2
- package/src/components/command-bar/helpers.ts +2 -6
- package/src/components/command-bar/keyboard-shortcuts.ts +0 -11
- package/src/components/command-bar/list/badge.test.ts +54 -0
- package/src/components/command-bar/list/badge.ts +62 -0
- package/src/components/command-bar/list/model.test.ts +103 -0
- package/src/components/command-bar/list/model.ts +61 -4
- package/src/components/command-bar/list/view.test.tsx +113 -0
- package/src/components/command-bar/list/view.tsx +147 -131
- package/src/components/command-bar/pane-templates/workflow.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +51 -65
- package/src/components/command-bar/panel/index.tsx +48 -13
- package/src/components/command-bar/panel/layout.test.ts +139 -0
- package/src/components/command-bar/panel/layout.ts +65 -28
- package/src/components/command-bar/panel/native-surface.ts +24 -0
- package/src/components/command-bar/panel/prompt-binding.ts +54 -0
- package/src/components/command-bar/panel/runtime.ts +6 -3
- package/src/components/command-bar/panel/state.ts +41 -7
- package/src/components/command-bar/panel/types.ts +7 -1
- package/src/components/command-bar/routes/root/provider-search.ts +34 -15
- package/src/components/command-bar/routes/root/results.test.ts +161 -0
- package/src/components/command-bar/routes/root/results.ts +30 -28
- package/src/components/command-bar/routes/root/runtime.ts +37 -20
- package/src/components/command-bar/routes/root/search-providers.test.tsx +224 -0
- package/src/components/command-bar/routes/root/search-providers.ts +205 -0
- package/src/components/command-bar/routes/root/selection.ts +1 -12
- package/src/components/command-bar/routes/root/shortcuts.test.ts +8 -8
- package/src/components/command-bar/routes/ticker-search/actions.ts +10 -9
- package/src/components/command-bar/routes/ticker-search/results.test.ts +54 -1
- package/src/components/command-bar/routes/ticker-search/results.ts +60 -19
- package/src/components/command-bar/routes/ticker-search/route.ts +1 -0
- package/src/components/command-bar/routing/actions.ts +1 -81
- package/src/components/command-bar/routing/launch-request.ts +1 -1
- package/src/components/command-bar/routing/list-state.ts +6 -21
- package/src/components/command-bar/selection-runtime.ts +1 -1
- package/src/components/command-bar/surface/assist.test.tsx +14 -10
- package/src/components/command-bar/surface/environment.ts +8 -1
- package/src/components/command-bar/surface/index.test.tsx +84 -68
- package/src/components/command-bar/surface/index.tsx +33 -36
- package/src/components/command-bar/surface/test-harness.tsx +15 -3
- package/src/components/command-bar/theme-picker.tsx +43 -15
- package/src/components/command-bar/view-model.test.ts +53 -8
- package/src/components/command-bar/view-model.ts +43 -14
- package/src/components/command-bar/workflow/tickers.ts +1 -0
- package/src/components/command-bar/workflow/types.ts +1 -1
- package/src/components/data-table/export.test.ts +21 -0
- package/src/components/data-table/export.ts +21 -0
- package/src/components/data-table/view.test.tsx +45 -6
- package/src/components/data-table/view.tsx +55 -9
- package/src/components/index.ts +10 -2
- package/src/components/input-search-bar.test.tsx +36 -2
- package/src/components/input-search-bar.tsx +18 -1
- package/src/components/layout/header.test.tsx +57 -10
- package/src/components/layout/header.tsx +292 -149
- package/src/components/layout/market-summary.test.ts +81 -0
- package/src/components/layout/market-summary.ts +109 -0
- package/src/components/layout/shell/chrome.ts +96 -1
- package/src/components/layout/shell/index.tsx +11 -3
- package/src/components/layout/shell/menu.ts +9 -0
- package/src/components/layout/shell/pane/actions.ts +29 -0
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/shortcuts.ts +3 -0
- package/src/components/layout/status-bar.test.tsx +9 -8
- package/src/components/layout/status-bar.tsx +85 -54
- package/src/components/onboarding/onboarding-frame.tsx +2 -26
- package/src/components/price-sparkline/index.ts +61 -34
- package/src/components/price-sparkline/view.tsx +1 -1
- package/src/components/sign-in-gate.test.tsx +128 -0
- package/src/components/sign-in-gate.tsx +149 -0
- package/src/components/speedometer-gauge/desktop.tsx +2 -12
- package/src/components/ticker/badge/list.tsx +17 -3
- package/src/components/ticker/list-table-view.tsx +6 -3
- package/src/components/ui/data-table/index.tsx +22 -4
- package/src/components/ui/data-table/opentui/index.tsx +165 -120
- package/src/components/ui/frame.tsx +28 -0
- package/src/components/ui/index.ts +3 -0
- package/src/components/ui/native-select.tsx +20 -10
- package/src/components/ui/select-button.tsx +138 -0
- package/src/components/ui/status.tsx +2 -2
- package/src/components/ui/table-layout.ts +1 -1
- package/src/components/use-double-click-activation.ts +7 -3
- package/src/core/app-services.ts +3 -3
- package/src/data/config/chart-settings.ts +4 -4
- package/src/data/config/layout.ts +12 -6
- package/src/data/config/store/index.test.ts +97 -0
- package/src/data/config/store/migrations.ts +41 -0
- package/src/data/config/store/normalize.ts +5 -3
- package/src/i18n/es.ts +6 -2
- package/src/i18n/ja.ts +6 -2
- package/src/i18n/ko.ts +6 -2
- package/src/i18n/zh-cn.ts +6 -2
- package/src/i18n/zh-tw.ts +6 -2
- package/src/layout-marketplace/gallery-terminal.tsx +126 -96
- package/src/layout-marketplace/gallery.test.tsx +65 -1
- package/src/layout-marketplace/pane-imagery.ts +1 -0
- package/src/layout-marketplace/payload.test.ts +17 -0
- package/src/layout-marketplace/payload.ts +40 -5
- package/src/market-data/coordinator/index.ts +3 -2
- package/src/market-data/coordinator/quotes.ts +173 -66
- package/src/market-data/coordinator/subscriptions.test.ts +215 -37
- package/src/pane-settings.ts +1 -1
- package/src/plugins/builtin/analytics/pane-model.ts +1 -1
- package/src/plugins/builtin/analytics/view.tsx +1 -1
- package/src/plugins/builtin/broker-manager/index.test.tsx +3 -2
- package/src/plugins/builtin/broker-manager/model.test.ts +2 -2
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +16 -2
- package/src/plugins/builtin/chart-composer/cli-options.ts +12 -9
- package/src/plugins/builtin/chart-composer/pane.tsx +22 -8
- package/src/plugins/builtin/chart-composer/settings.ts +2 -13
- package/src/plugins/builtin/chat/content/composer.tsx +8 -4
- package/src/plugins/builtin/cloud/auth-dialog.tsx +14 -228
- package/src/plugins/builtin/cloud/auth-form.tsx +277 -0
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/composite-plugins.ts +16 -1
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +2 -6
- package/src/plugins/builtin/correlation/relationship/view-model.ts +2 -2
- package/src/plugins/builtin/credit-conditions/index.test.tsx +12 -6
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -21
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/earnings/index.tsx +1 -0
- package/src/plugins/builtin/earnings-calls/data.ts +223 -0
- package/src/plugins/builtin/earnings-calls/format.ts +49 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +69 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +756 -0
- package/src/plugins/builtin/earnings-calls/prose.test.ts +36 -0
- package/src/plugins/builtin/earnings-calls/prose.ts +59 -0
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +334 -0
- package/src/plugins/builtin/econ/detail-view.tsx +1 -2
- package/src/plugins/builtin/econ/fred-series-map.ts +16 -1
- package/src/plugins/builtin/econ/index.tsx +3 -1
- package/src/plugins/builtin/econ-statistics/cache.ts +4 -0
- package/src/plugins/builtin/econ-statistics/client.ts +92 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +66 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +154 -0
- package/src/plugins/builtin/econ-statistics/headless.test.ts +54 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +171 -0
- package/src/plugins/builtin/econ-statistics/index.tsx +54 -0
- package/src/plugins/builtin/econ-statistics/pane.tsx +356 -0
- package/src/plugins/builtin/econ-statistics/stats.ts +522 -0
- package/src/plugins/builtin/econ-statistics/transform.test.ts +86 -0
- package/src/plugins/builtin/econ-statistics/transform.ts +85 -0
- package/src/plugins/builtin/econ-statistics/trend.ts +57 -0
- package/src/plugins/builtin/econ-statistics/view.ts +90 -0
- package/src/plugins/builtin/fear-greed/charts.tsx +7 -18
- package/src/plugins/builtin/fear-greed/data.ts +6 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +1 -0
- package/src/plugins/builtin/help/index.tsx +4 -0
- package/src/plugins/builtin/holders/index.tsx +1 -0
- package/src/plugins/builtin/insider/index.tsx +1 -0
- package/src/plugins/builtin/ipo-calendar/index.tsx +1 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/sections.tsx +2 -3
- package/src/plugins/builtin/market-halts/index.tsx +1 -0
- package/src/plugins/builtin/market-movers/index.tsx +1 -0
- package/src/plugins/builtin/market-valuation/align.ts +122 -0
- package/src/plugins/builtin/market-valuation/cache.ts +32 -0
- package/src/plugins/builtin/market-valuation/chart-projection.ts +217 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +89 -0
- package/src/plugins/builtin/market-valuation/client.test.ts +141 -0
- package/src/plugins/builtin/market-valuation/client.ts +116 -0
- package/src/plugins/builtin/market-valuation/defs.ts +251 -0
- package/src/plugins/builtin/market-valuation/detail.tsx +159 -0
- package/src/plugins/builtin/market-valuation/headless.test.ts +58 -0
- package/src/plugins/builtin/market-valuation/headless.ts +170 -0
- package/src/plugins/builtin/market-valuation/index.tsx +64 -0
- package/src/plugins/builtin/market-valuation/indicators.ts +422 -0
- package/src/plugins/builtin/market-valuation/model.test.ts +350 -0
- package/src/plugins/builtin/market-valuation/model.ts +8 -0
- package/src/plugins/builtin/market-valuation/pane.test.tsx +247 -0
- package/src/plugins/builtin/market-valuation/pane.tsx +344 -0
- package/src/plugins/builtin/market-valuation/series.ts +12 -0
- package/src/plugins/builtin/market-valuation/settings.ts +38 -0
- package/src/plugins/builtin/market-valuation/sources.ts +130 -0
- package/src/plugins/builtin/market-valuation/trend.ts +89 -0
- package/src/plugins/builtin/market-valuation/view.ts +137 -0
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +123 -0
- package/src/plugins/builtin/market-valuation/zone-scale/index.tsx +12 -0
- package/src/plugins/builtin/market-valuation/zone-scale/model.ts +60 -0
- package/src/plugins/builtin/market-valuation/zone-scale/terminal.tsx +94 -0
- package/src/plugins/builtin/news/wire/breaking/filters.test.ts +99 -0
- package/src/plugins/builtin/news/wire/breaking/filters.ts +110 -0
- package/src/plugins/builtin/news/wire/breaking/notifications.test.ts +157 -53
- package/src/plugins/builtin/news/wire/breaking/notifications.ts +91 -25
- package/src/plugins/builtin/news/wire/index.tsx +31 -44
- package/src/plugins/builtin/options/analytics.test.ts +83 -0
- package/src/plugins/builtin/options/analytics.ts +110 -0
- package/src/plugins/builtin/options/index.tsx +18 -2
- package/src/plugins/builtin/options/table.ts +121 -51
- package/src/plugins/builtin/options/types.ts +22 -15
- package/src/plugins/builtin/options/view.test.tsx +53 -1
- package/src/plugins/builtin/options/view.tsx +92 -41
- package/src/plugins/builtin/plugin-marketplace/feed.ts +80 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +31 -0
- package/src/plugins/builtin/plugin-marketplace/model.test.ts +200 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +204 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +385 -0
- package/src/plugins/builtin/plugin-marketplace/store.ts +46 -0
- package/src/plugins/builtin/plugin-module.test.ts +2 -4
- package/src/plugins/builtin/plugin-module.ts +9 -8
- package/src/plugins/builtin/portfolio-list/index.tsx +1 -0
- package/src/plugins/builtin/research/index.tsx +4 -0
- package/src/plugins/builtin/research-search/command-bar-search.test.ts +81 -0
- package/src/plugins/builtin/research-search/command-bar-search.ts +175 -0
- package/src/plugins/builtin/research-search/data.ts +109 -0
- package/src/plugins/builtin/research-search/document-view.test.tsx +75 -0
- package/src/plugins/builtin/research-search/document-view.tsx +254 -0
- package/src/plugins/builtin/research-search/filter-bar.tsx +62 -0
- package/src/plugins/builtin/research-search/focus-handoff.ts +47 -0
- package/src/plugins/builtin/research-search/index.tsx +85 -0
- package/src/plugins/builtin/research-search/model.test.ts +40 -0
- package/src/plugins/builtin/research-search/model.ts +291 -0
- package/src/plugins/builtin/research-search/pane.test.tsx +241 -0
- package/src/plugins/builtin/research-search/pane.tsx +678 -0
- package/src/plugins/builtin/research-search/saved-view.tsx +171 -0
- package/src/plugins/builtin/research-search/snippet-text.tsx +35 -0
- package/src/plugins/builtin/research-search/snippet.test.ts +78 -0
- package/src/plugins/builtin/research-search/snippet.ts +134 -0
- package/src/plugins/builtin/scanner/flow-model.test.ts +11 -1
- package/src/plugins/builtin/scanner/flow-model.ts +29 -1
- package/src/plugins/builtin/scanner/flow-pane.tsx +78 -22
- package/src/plugins/builtin/scanner/index.ts +2 -0
- package/src/plugins/builtin/sec/index.tsx +1 -0
- package/src/plugins/builtin/sectors/index.tsx +1 -0
- package/src/plugins/builtin/shared/series-cache.ts +93 -0
- package/src/plugins/builtin/short-interest/index.tsx +1 -0
- package/src/plugins/builtin/short-interest/pane.tsx +1 -1
- package/src/plugins/builtin/thirteenf/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +3 -5
- package/src/plugins/builtin/ticker-detail/index.tsx +2 -14
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +1 -1
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/world-indices/index.tsx +1 -0
- package/src/plugins/builtin/world-venue-map/index.ts +27 -0
- package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +106 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +481 -0
- package/src/plugins/builtin/world-venue-map/model.test.ts +85 -0
- package/src/plugins/builtin/world-venue-map/model.ts +268 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +300 -0
- package/src/plugins/builtin/world-venue-map/world-outlines.ts +2 -0
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/bundle.test.ts +109 -0
- package/src/plugins/bundle.ts +139 -0
- package/src/plugins/catalog-backend.ts +6 -44
- package/src/plugins/catalog-browser.test.ts +1 -0
- package/src/plugins/catalog-browser.ts +12 -0
- package/src/plugins/catalog-manifest.test.ts +43 -0
- package/src/plugins/catalog-manifest.ts +92 -0
- package/src/plugins/catalog-ui.ts +20 -4
- package/src/plugins/catalog.ts +9 -2
- package/src/plugins/current-target.ts +28 -0
- package/src/plugins/host-contract.ts +37 -0
- package/src/plugins/host-link.ts +158 -0
- package/src/plugins/host-modules.ts +61 -0
- package/src/plugins/loader.ts +41 -22
- package/src/plugins/ownership.ts +1 -0
- package/src/plugins/prediction-markets/index.tsx +1 -0
- package/src/plugins/registry/context.ts +3 -0
- package/src/plugins/registry/contributions.ts +27 -0
- package/src/plugins/registry/index.test.ts +25 -0
- package/src/plugins/registry/index.ts +8 -0
- package/src/plugins/registry/pane-settings.test.ts +53 -0
- package/src/plugins/registry/pane-settings.ts +29 -3
- package/src/plugins/seed.test.ts +83 -0
- package/src/plugins/seed.ts +80 -0
- package/src/public/broker.ts +31 -0
- package/src/public/market-data.ts +9 -0
- package/src/public/pane-hooks.ts +57 -0
- package/src/public/public-api.test.ts +285 -0
- package/src/public/react.ts +62 -0
- package/src/public/test-support.ts +23 -0
- package/src/public/time-series.ts +8 -0
- package/src/public/utils.ts +77 -0
- package/src/remote/layout-helpers.ts +6 -8
- package/src/remote/resources.ts +2 -0
- package/src/remote/schema.ts +1 -0
- package/src/remote/semantic-tree.test.tsx +105 -0
- package/src/remote/semantic-tree.tsx +53 -35
- package/src/renderers/browser/main.tsx +6 -0
- package/src/renderers/browser/ui-host.tsx +11 -0
- package/src/renderers/cloudflare/worker.test.ts +19 -0
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -2
- package/src/renderers/electrobun/bun/external-plugins.ts +140 -0
- package/src/renderers/electrobun/bun/index.ts +6 -2
- package/src/renderers/electrobun/shared/protocol.ts +25 -0
- package/src/renderers/electrobun/view/build-assets.ts +0 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +51 -1
- package/src/renderers/electrobun/view/external-plugins.test.ts +45 -0
- package/src/renderers/electrobun/view/external-plugins.ts +63 -0
- package/src/renderers/electrobun/view/host/ascii-text.test.ts +48 -0
- package/src/renderers/electrobun/view/host/ascii-text.ts +11 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +38 -32
- package/src/renderers/electrobun/view/host/mouse.ts +16 -2
- package/src/renderers/electrobun/view/main.tsx +27 -2
- package/src/renderers/electrobun/view/styles.css +5 -0
- package/src/renderers/electrobun/view/toast-host.tsx +18 -0
- package/src/renderers/electrobun/view/ui-host.tsx +3 -0
- package/src/renderers/opentui/chart-surface.tsx +5 -1
- package/src/renderers/opentui/host.tsx +20 -2
- package/src/renderers/opentui/interaction-performance.test.ts +79 -0
- package/src/renderers/opentui/interaction-performance.ts +188 -0
- package/src/renderers/opentui/start.tsx +26 -1
- package/src/renderers/opentui/test-utils.tsx +13 -0
- package/src/renderers/opentui/toast-host.tsx +26 -2
- package/src/renderers/opentui/ui-host.tsx +1 -0
- package/src/sources/provider-router/search.test.ts +191 -0
- package/src/sources/provider-router/search.ts +92 -39
- package/src/state/app/context/index.tsx +2 -0
- package/src/state/app/context/selector.test.tsx +33 -1
- package/src/state/hooks/quote-streaming.test.tsx +93 -0
- package/src/state/hooks/quote-streaming.ts +106 -30
- package/src/state/pane-table-export-registry.ts +50 -0
- package/src/theme/color-utils.ts +1 -1
- package/src/theme/colors.ts +50 -0
- package/src/theme/themes.test.ts +15 -2
- package/src/theme/themes.ts +19 -1
- package/src/tickers/search/index.test.ts +26 -0
- package/src/tickers/search/index.ts +42 -17
- package/src/tickers/search/ranking.ts +14 -0
- package/src/time-series/chart-data.test.ts +216 -0
- package/src/time-series/range.ts +12 -0
- package/src/time-series/resolution.test.ts +25 -26
- package/src/time-series/resolution.ts +44 -25
- package/src/time-series/resolve.ts +7 -0
- package/src/time-series/spec.ts +5 -5
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.ts +5 -0
- package/src/types/config.ts +123 -3
- package/src/types/data-provider.ts +11 -0
- package/src/types/headless.ts +161 -0
- package/src/types/plugin.ts +104 -20
- package/src/ui/host.tsx +19 -1
- package/src/ui/index.tsx +1 -0
- package/src/ui/toast.tsx +8 -4
- package/src/utils/csv.test.ts +13 -0
- package/src/utils/csv.ts +37 -0
- package/src/utils/format.ts +35 -0
- package/src/utils/fuzzy-search.test.ts +94 -0
- package/src/utils/fuzzy-search.ts +81 -22
- package/src/utils/save-text-file.test.ts +24 -0
- package/src/utils/save-text-file.ts +36 -0
- package/src/utils/shortcut-labels.ts +14 -0
- package/src/components/chart/core/axis-format.ts +0 -157
- package/src/components/chart/core/index.test.ts +0 -1075
- package/src/components/chart/core/projection.ts +0 -357
- package/src/components/chart/core/render-utils.ts +0 -4
- package/src/components/chart/core/renderer.ts +0 -244
- package/src/components/chart/core/scene.ts +0 -180
- package/src/components/chart/core/time-axis.ts +0 -330
- package/src/components/chart/cursor-motion.ts +0 -47
- package/src/components/chart/indicators/types.ts +0 -26
- package/src/components/chart/market-session.ts +0 -176
- package/src/components/chart/multi-line/renderer.test.ts +0 -83
- package/src/components/chart/multi-line/renderer.ts +0 -161
- package/src/components/chart/multi-line/scene.ts +0 -188
- package/src/components/chart/native/raster/layout.ts +0 -129
- package/src/components/chart/native/raster/price-chart.ts +0 -244
- package/src/components/chart/rendering/chart-draw.ts +0 -270
- package/src/components/chart/rendering/geometry.ts +0 -95
- package/src/components/chart/rendering/pixel-buffer.ts +0 -267
- package/src/components/chart/scatter-chart-renderer.test.ts +0 -31
- package/src/components/chart/scatter-chart-renderer.ts +0 -223
- package/src/components/chart/static/chart/surface.tsx +0 -358
- package/src/components/command-bar/routes/root/article-results.test.ts +0 -83
- package/src/components/command-bar/routes/root/article-results.ts +0 -55
- package/src/plugins/builtin/news/wire/article-search.test.ts +0 -72
- package/src/plugins/builtin/news/wire/article-search.ts +0 -140
- package/src/plugins/builtin/substack/api/auth.ts +0 -185
- package/src/plugins/builtin/substack/api/cache.ts +0 -82
- package/src/plugins/builtin/substack/api/loaders.ts +0 -170
- package/src/plugins/builtin/substack/api/store.ts +0 -186
- package/src/plugins/builtin/substack/api/types.ts +0 -42
- package/src/plugins/builtin/substack/api.test.ts +0 -298
- package/src/plugins/builtin/substack/article-detail.tsx +0 -397
- package/src/plugins/builtin/substack/article-stack.tsx +0 -133
- package/src/plugins/builtin/substack/content.ts +0 -478
- package/src/plugins/builtin/substack/feed-tabs.tsx +0 -44
- package/src/plugins/builtin/substack/index.tsx +0 -49
- package/src/plugins/builtin/substack/login-view.tsx +0 -126
- package/src/plugins/builtin/substack/model.test.ts +0 -155
- package/src/plugins/builtin/substack/normalize.ts +0 -343
- package/src/plugins/builtin/substack/pane-footer.ts +0 -52
- package/src/plugins/builtin/substack/pane-state.ts +0 -170
- package/src/plugins/builtin/substack/pane.tsx +0 -547
- package/src/plugins/builtin/substack/read-state.ts +0 -30
- package/src/plugins/builtin/substack/table.ts +0 -111
- package/src/plugins/builtin/substack/types.ts +0 -71
- package/src/plugins/builtin/substack/utils.ts +0 -131
- package/src/plugins/builtin/ticker-detail/data-panes/provider-search.tsx +0 -229
- package/src/plugins/ibkr/account-cache.test.ts +0 -102
- package/src/plugins/ibkr/account-cache.ts +0 -24
- package/src/plugins/ibkr/broker-adapter.ts +0 -286
- package/src/plugins/ibkr/config.test.ts +0 -79
- package/src/plugins/ibkr/config.ts +0 -250
- package/src/plugins/ibkr/dialogs.tsx +0 -40
- package/src/plugins/ibkr/flex/index.test.ts +0 -264
- package/src/plugins/ibkr/flex/index.ts +0 -367
- package/src/plugins/ibkr/flex/statement-client.ts +0 -235
- package/src/plugins/ibkr/fundamental-parser.ts +0 -149
- package/src/plugins/ibkr/gateway/account-loaders.ts +0 -266
- package/src/plugins/ibkr/gateway/account-summary.ts +0 -164
- package/src/plugins/ibkr/gateway/client-lock.ts +0 -154
- package/src/plugins/ibkr/gateway/connection-events.ts +0 -114
- package/src/plugins/ibkr/gateway/connection.ts +0 -152
- package/src/plugins/ibkr/gateway/contracts.ts +0 -132
- package/src/plugins/ibkr/gateway/fundamentals.ts +0 -83
- package/src/plugins/ibkr/gateway/helpers.ts +0 -33
- package/src/plugins/ibkr/gateway/history-requests.ts +0 -158
- package/src/plugins/ibkr/gateway/history.ts +0 -120
- package/src/plugins/ibkr/gateway/instrument-lookup.ts +0 -117
- package/src/plugins/ibkr/gateway/market-data.ts +0 -345
- package/src/plugins/ibkr/gateway/order-execution.ts +0 -218
- package/src/plugins/ibkr/gateway/orders.ts +0 -63
- package/src/plugins/ibkr/gateway/price-normalization.test.ts +0 -44
- package/src/plugins/ibkr/gateway/price-normalization.ts +0 -50
- package/src/plugins/ibkr/gateway/quote-stream-controller.ts +0 -203
- package/src/plugins/ibkr/gateway/quote-stream.ts +0 -171
- package/src/plugins/ibkr/gateway/selection.ts +0 -51
- package/src/plugins/ibkr/gateway/service/index.test.ts +0 -675
- package/src/plugins/ibkr/gateway/service/index.ts +0 -429
- package/src/plugins/ibkr/gateway/service/lifecycle.ts +0 -191
- package/src/plugins/ibkr/gateway/service/manager.ts +0 -52
- package/src/plugins/ibkr/gateway/service/market-data.ts +0 -48
- package/src/plugins/ibkr/gateway/service/native-loader.ts +0 -12
- package/src/plugins/ibkr/gateway/service/native.ts +0 -543
- package/src/plugins/ibkr/gateway/timeouts.ts +0 -13
- package/src/plugins/ibkr/gateway/types.ts +0 -27
- package/src/plugins/ibkr/index.test.tsx +0 -162
- package/src/plugins/ibkr/index.tsx +0 -159
- package/src/plugins/ibkr/instance-selection.test.ts +0 -120
- package/src/plugins/ibkr/instance-selection.ts +0 -36
- package/src/plugins/ibkr/portfolio-performance.test.ts +0 -32
- package/src/plugins/ibkr/portfolio-performance.ts +0 -129
- package/src/plugins/ibkr/trade/badge.tsx +0 -28
- package/src/plugins/ibkr/trade/dialogs.tsx +0 -44
- package/src/plugins/ibkr/trade/preview-panel.tsx +0 -130
- package/src/plugins/ibkr/trade/tab/actions.tsx +0 -443
- package/src/plugins/ibkr/trade/tab/field-editors.tsx +0 -79
- package/src/plugins/ibkr/trade/tab/footer.ts +0 -53
- package/src/plugins/ibkr/trade/tab/header.tsx +0 -167
- package/src/plugins/ibkr/trade/tab/index.test.tsx +0 -178
- package/src/plugins/ibkr/trade/tab/index.tsx +0 -298
- package/src/plugins/ibkr/trade/tab/model.ts +0 -159
- package/src/plugins/ibkr/trade/tab/order-request.ts +0 -64
- package/src/plugins/ibkr/trade/tab/shortcuts.ts +0 -89
- package/src/plugins/ibkr/trade/tab/state-sync.ts +0 -86
- package/src/plugins/ibkr/trade/ticket-panel.tsx +0 -301
- package/src/plugins/ibkr/trade/utils.test.ts +0 -175
- package/src/plugins/ibkr/trade/utils.ts +0 -144
- package/src/plugins/ibkr/trading/pane-view.tsx +0 -237
- package/src/plugins/ibkr/trading/pane.tsx +0 -332
- package/src/plugins/ibkr/trading/state.test.ts +0 -109
- package/src/plugins/ibkr/trading/state.ts +0 -335
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { afterEach, expect, test } from "bun:test";
|
|
2
|
+
import { act } from "react";
|
|
3
|
+
import { testRender } from "../../../renderers/opentui/test-utils";
|
|
4
|
+
import { CommandBarListBody } from "./view";
|
|
5
|
+
import type { CommandBarListRow, ListScreenState, ResultItem } from "./model";
|
|
6
|
+
|
|
7
|
+
let testSetup: Awaited<ReturnType<typeof testRender>> | undefined;
|
|
8
|
+
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
testSetup?.renderer.destroy();
|
|
11
|
+
testSetup = undefined;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function item(overrides: Partial<ResultItem> & { id: string; label: string }): ResultItem {
|
|
15
|
+
return {
|
|
16
|
+
detail: "",
|
|
17
|
+
category: "Commands",
|
|
18
|
+
kind: "command",
|
|
19
|
+
action: () => {},
|
|
20
|
+
...overrides,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function rows(items: ResultItem[]): CommandBarListRow[] {
|
|
25
|
+
return [
|
|
26
|
+
{ kind: "heading", id: "heading", label: "Commands" },
|
|
27
|
+
...items.map((entry, index) => ({ kind: "item" as const, item: entry, globalIdx: index })),
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const LIST_STATE: ListScreenState = {
|
|
32
|
+
kind: "root",
|
|
33
|
+
title: "Commands",
|
|
34
|
+
query: "port",
|
|
35
|
+
selectedIdx: -1,
|
|
36
|
+
hoveredIdx: null,
|
|
37
|
+
results: [],
|
|
38
|
+
searching: false,
|
|
39
|
+
emptyLabel: "",
|
|
40
|
+
emptyDetail: "",
|
|
41
|
+
footerLeft: "",
|
|
42
|
+
footerRight: "",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function ListHarness({ nativeListRows }: { nativeListRows: CommandBarListRow[] }) {
|
|
46
|
+
return (
|
|
47
|
+
<CommandBarListBody
|
|
48
|
+
visibleListState={LIST_STATE}
|
|
49
|
+
nativeListRows={nativeListRows}
|
|
50
|
+
listBodyHeight={16}
|
|
51
|
+
contentPadding={3}
|
|
52
|
+
labelWidth={40}
|
|
53
|
+
nativePaneChrome={false}
|
|
54
|
+
nativeListScrollRef={{ current: null }}
|
|
55
|
+
paletteAccentText="#ffffff"
|
|
56
|
+
paletteBg="#000000"
|
|
57
|
+
paletteHeadingText="#ffffff"
|
|
58
|
+
paletteHoverBg="#000000"
|
|
59
|
+
paletteMatchText="#ffffff"
|
|
60
|
+
paletteSelectedBg="#000000"
|
|
61
|
+
paletteSelectedText="#ffffff"
|
|
62
|
+
paletteSubtleText="#ffffff"
|
|
63
|
+
paletteText="#ffffff"
|
|
64
|
+
panelBg="#000000"
|
|
65
|
+
queryDisplayWidth={50}
|
|
66
|
+
trailingWidth={10}
|
|
67
|
+
onHoverIndex={() => {}}
|
|
68
|
+
onListScroll={() => {}}
|
|
69
|
+
onRowMouseDown={() => {}}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function columnOf(frame: string, text: string): number {
|
|
75
|
+
const line = frame.split("\n").find((row) => row.includes(text));
|
|
76
|
+
return line ? line.indexOf(text) : -1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Instruments and documents arrive after the local rows and carry wider badges
|
|
81
|
+
* than they do, so a column measured from what is on screen would widen
|
|
82
|
+
* mid-query and drag every label already rendered to the right.
|
|
83
|
+
*/
|
|
84
|
+
test("keeps labels in place when a later section brings wider badges", async () => {
|
|
85
|
+
const local = [
|
|
86
|
+
item({ id: "portfolio", label: "Open Portfolio" }),
|
|
87
|
+
item({ id: "quote", label: "Quote", right: "Q" }),
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
testSetup = await testRender(<ListHarness nativeListRows={rows(local)} />, { width: 60, height: 20 });
|
|
91
|
+
await testSetup.renderOnce();
|
|
92
|
+
const before = testSetup.captureCharFrame();
|
|
93
|
+
testSetup.renderer.destroy();
|
|
94
|
+
testSetup = await testRender(
|
|
95
|
+
<ListHarness
|
|
96
|
+
nativeListRows={rows([
|
|
97
|
+
...local,
|
|
98
|
+
item({ id: "spy", label: "SPDR S&P 500", kind: "search", badge: "ETF" }),
|
|
99
|
+
item({ id: "filing", label: "Annual report", kind: "action", badge: "10-K" }),
|
|
100
|
+
item({ id: "derivative", label: "Call spread", kind: "search", badge: "DERIV" }),
|
|
101
|
+
])}
|
|
102
|
+
/>,
|
|
103
|
+
{ width: 60, height: 20 },
|
|
104
|
+
);
|
|
105
|
+
await testSetup.renderOnce();
|
|
106
|
+
const after = testSetup.captureCharFrame();
|
|
107
|
+
|
|
108
|
+
expect(columnOf(before, "Open Portfolio")).toBeGreaterThan(0);
|
|
109
|
+
expect(columnOf(after, "Open Portfolio")).toBe(columnOf(before, "Open Portfolio"));
|
|
110
|
+
expect(columnOf(after, "Commands")).toBe(columnOf(before, "Commands"));
|
|
111
|
+
// The widest badge ends one gap short of the label edge it shares.
|
|
112
|
+
expect(columnOf(after, "DERIV") + "DERIV".length).toBe(columnOf(after, "Call spread") - 1);
|
|
113
|
+
});
|
|
@@ -1,16 +1,30 @@
|
|
|
1
|
-
import { memo,
|
|
1
|
+
import { memo, useMemo, type RefObject } from "react";
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
|
-
Input,
|
|
5
4
|
ScrollBox,
|
|
6
5
|
Text,
|
|
7
6
|
TextAttributes,
|
|
8
|
-
type InputRenderable,
|
|
9
7
|
type ScrollBoxRenderable,
|
|
10
8
|
} from "../../../ui";
|
|
11
9
|
import { Spinner } from "../../ui";
|
|
12
10
|
import { t } from "../../../i18n";
|
|
13
|
-
import
|
|
11
|
+
import { commandBarBadgeText, type CommandBarBadgeTone } from "../../../theme/colors";
|
|
12
|
+
import { useThemeColors } from "../../../theme/theme-context";
|
|
13
|
+
import type { CommandBarResultLineSegment } from "../../../types/plugin";
|
|
14
|
+
import { truncateTextSegments } from "../../../utils/format";
|
|
15
|
+
import {
|
|
16
|
+
BADGE_COLUMN_WIDTH,
|
|
17
|
+
BADGE_GAP,
|
|
18
|
+
badgeConsumesRight,
|
|
19
|
+
resolveRowBadge,
|
|
20
|
+
} from "./badge";
|
|
21
|
+
import {
|
|
22
|
+
getListRowsHeight,
|
|
23
|
+
getResultItemLines,
|
|
24
|
+
type CommandBarListRow,
|
|
25
|
+
type ListScreenState,
|
|
26
|
+
type ResultItem,
|
|
27
|
+
} from "./model";
|
|
14
28
|
import { getRowPresentation, truncateText } from "../view-model";
|
|
15
29
|
import { useRemoteUiNode } from "../../../remote/semantic-tree";
|
|
16
30
|
|
|
@@ -20,109 +34,8 @@ export type CommandBarListScrollEvent = {
|
|
|
20
34
|
scroll?: { direction?: string; delta?: number };
|
|
21
35
|
};
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
title: string;
|
|
26
|
-
query: string;
|
|
27
|
-
queryDisplayWidth: number;
|
|
28
|
-
nativePaneChrome: boolean;
|
|
29
|
-
inputBg: string;
|
|
30
|
-
paletteBg: string;
|
|
31
|
-
paletteText: string;
|
|
32
|
-
paletteSubtleText: string;
|
|
33
|
-
cursorColor: string;
|
|
34
|
-
contentPadding: number;
|
|
35
|
-
rootGhostSuffix: string | null;
|
|
36
|
-
rootQueryLength: number;
|
|
37
|
-
rootShortcutFeedback: string | null;
|
|
38
|
-
onQueryChange: (query: string) => void;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const CommandBarListHeader = memo(function CommandBarListHeader({
|
|
42
|
-
kind,
|
|
43
|
-
title,
|
|
44
|
-
query,
|
|
45
|
-
queryDisplayWidth,
|
|
46
|
-
nativePaneChrome,
|
|
47
|
-
inputBg,
|
|
48
|
-
paletteBg,
|
|
49
|
-
paletteText,
|
|
50
|
-
paletteSubtleText,
|
|
51
|
-
cursorColor,
|
|
52
|
-
contentPadding,
|
|
53
|
-
rootGhostSuffix,
|
|
54
|
-
rootQueryLength,
|
|
55
|
-
rootShortcutFeedback,
|
|
56
|
-
onQueryChange,
|
|
57
|
-
}: CommandBarListHeaderProps) {
|
|
58
|
-
const inputRef = useRef<InputRenderable | null>(null);
|
|
59
|
-
|
|
60
|
-
useLayoutEffect(() => {
|
|
61
|
-
const input = inputRef.current;
|
|
62
|
-
if (!input || input.editBuffer.getText() === query) return;
|
|
63
|
-
input.editBuffer.setText?.(query);
|
|
64
|
-
input.setCursorOffset?.(query.length);
|
|
65
|
-
}, [kind, query, title]);
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<>
|
|
69
|
-
<Box height={1} paddingX={contentPadding}>
|
|
70
|
-
<Box
|
|
71
|
-
width={queryDisplayWidth}
|
|
72
|
-
height={1}
|
|
73
|
-
position="relative"
|
|
74
|
-
backgroundColor={nativePaneChrome ? undefined : inputBg}
|
|
75
|
-
style={nativePaneChrome ? undefined : {
|
|
76
|
-
overflow: "hidden",
|
|
77
|
-
}}
|
|
78
|
-
>
|
|
79
|
-
<Input
|
|
80
|
-
key={`${kind}:${title}`}
|
|
81
|
-
ref={inputRef}
|
|
82
|
-
value={query}
|
|
83
|
-
onInput={onQueryChange}
|
|
84
|
-
placeholder={kind === "root" ? t("Command or plain English…") : title === "Security Description" ? t("Search tickers") : t("Filter")}
|
|
85
|
-
focused
|
|
86
|
-
data-gloom-remote-scope="command-bar"
|
|
87
|
-
data-gloom-remote-surface="command-bar"
|
|
88
|
-
width={nativePaneChrome ? "100%" : queryDisplayWidth}
|
|
89
|
-
backgroundColor={nativePaneChrome ? "transparent" : paletteBg}
|
|
90
|
-
focusedBackgroundColor={nativePaneChrome ? "transparent" : paletteBg}
|
|
91
|
-
textColor={paletteText}
|
|
92
|
-
focusedTextColor={paletteText}
|
|
93
|
-
placeholderColor={paletteSubtleText}
|
|
94
|
-
cursorColor={cursorColor}
|
|
95
|
-
/>
|
|
96
|
-
{kind === "root" && rootGhostSuffix && (
|
|
97
|
-
<Box
|
|
98
|
-
position="absolute"
|
|
99
|
-
top={0}
|
|
100
|
-
left={Math.max(0, Math.min(rootQueryLength, queryDisplayWidth - 1))}
|
|
101
|
-
width={Math.max(0, queryDisplayWidth - Math.min(rootQueryLength, queryDisplayWidth - 1))}
|
|
102
|
-
height={1}
|
|
103
|
-
>
|
|
104
|
-
<Text fg={paletteSubtleText}>
|
|
105
|
-
{truncateText(
|
|
106
|
-
rootGhostSuffix,
|
|
107
|
-
Math.max(0, queryDisplayWidth - Math.min(rootQueryLength, queryDisplayWidth - 1)),
|
|
108
|
-
)}
|
|
109
|
-
</Text>
|
|
110
|
-
</Box>
|
|
111
|
-
)}
|
|
112
|
-
</Box>
|
|
113
|
-
</Box>
|
|
114
|
-
<Box height={1} paddingX={contentPadding}>
|
|
115
|
-
{kind === "root" && rootShortcutFeedback
|
|
116
|
-
? (
|
|
117
|
-
<Text fg={paletteSubtleText}>
|
|
118
|
-
{truncateText(rootShortcutFeedback, queryDisplayWidth)}
|
|
119
|
-
</Text>
|
|
120
|
-
)
|
|
121
|
-
: null}
|
|
122
|
-
</Box>
|
|
123
|
-
</>
|
|
124
|
-
);
|
|
125
|
-
});
|
|
37
|
+
/** Columns every row gives up to the badge column, badge or not. */
|
|
38
|
+
const BADGE_INDENT = BADGE_COLUMN_WIDTH + BADGE_GAP;
|
|
126
39
|
|
|
127
40
|
interface CommandBarListItemRowProps {
|
|
128
41
|
item: ResultItem;
|
|
@@ -138,7 +51,9 @@ interface CommandBarListItemRowProps {
|
|
|
138
51
|
nativePaneChrome: boolean;
|
|
139
52
|
paletteAccentText: string;
|
|
140
53
|
paletteBg: string;
|
|
54
|
+
paletteHeadingText: string;
|
|
141
55
|
paletteHoverBg: string;
|
|
56
|
+
paletteMatchText: string;
|
|
142
57
|
paletteSelectedBg: string;
|
|
143
58
|
paletteSelectedText: string;
|
|
144
59
|
paletteSubtleText: string;
|
|
@@ -163,7 +78,9 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
|
|
|
163
78
|
nativePaneChrome,
|
|
164
79
|
paletteAccentText,
|
|
165
80
|
paletteBg,
|
|
81
|
+
paletteHeadingText,
|
|
166
82
|
paletteHoverBg,
|
|
83
|
+
paletteMatchText,
|
|
167
84
|
paletteSelectedBg,
|
|
168
85
|
paletteSelectedText,
|
|
169
86
|
paletteSubtleText,
|
|
@@ -174,8 +91,27 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
|
|
|
174
91
|
onRowMouseDown,
|
|
175
92
|
}: CommandBarListItemRowProps) {
|
|
176
93
|
const presentation = getRowPresentation(item, isSelected, trailingWidth > 0);
|
|
177
|
-
const
|
|
178
|
-
|
|
94
|
+
const badge = resolveRowBadge(item);
|
|
95
|
+
// The badge column and its gap come out of the label, so the right column
|
|
96
|
+
// stays where it is for rows with and without a badge alike.
|
|
97
|
+
const labelColumnWidth = Math.max(1, labelWidth - BADGE_INDENT);
|
|
98
|
+
// A long title stops one cell short of the right column, so its ellipsis
|
|
99
|
+
// never runs into the date or shortcut sitting there.
|
|
100
|
+
const label = truncateText(presentation.label, Math.max(1, labelColumnWidth - (trailingWidth > 0 ? 1 : 0)));
|
|
101
|
+
// "current" outranks the shortcut on the right; otherwise a badge lifted from
|
|
102
|
+
// `right` must not be repeated there.
|
|
103
|
+
const trailing = badgeConsumesRight(item) && !item.current
|
|
104
|
+
? ""
|
|
105
|
+
: truncateText(presentation.trailing, trailingWidth);
|
|
106
|
+
const lineWidth = labelColumnWidth + trailingWidth;
|
|
107
|
+
const lines = useMemo(
|
|
108
|
+
() => getResultItemLines(item).map((line) => truncateTextSegments(
|
|
109
|
+
line.segments,
|
|
110
|
+
lineWidth,
|
|
111
|
+
(ellipsis) => ({ text: ellipsis, emphasis: "muted" as const }),
|
|
112
|
+
)),
|
|
113
|
+
[item, lineWidth],
|
|
114
|
+
);
|
|
179
115
|
const activate = () => onRowMouseDown({
|
|
180
116
|
preventDefault() {},
|
|
181
117
|
stopPropagation() {},
|
|
@@ -215,8 +151,8 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
|
|
|
215
151
|
return (
|
|
216
152
|
<Box
|
|
217
153
|
key={item.id}
|
|
218
|
-
flexDirection="
|
|
219
|
-
height={1}
|
|
154
|
+
flexDirection="column"
|
|
155
|
+
height={1 + lines.length}
|
|
220
156
|
paddingX={contentPadding}
|
|
221
157
|
backgroundColor={isSelected
|
|
222
158
|
? paletteSelectedBg
|
|
@@ -230,26 +166,95 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
|
|
|
230
166
|
data-command-bar-row-selected={nativePaneChrome && isSelected ? "true" : undefined}
|
|
231
167
|
style={nativePaneChrome ? { borderRadius: 6 } : undefined}
|
|
232
168
|
>
|
|
233
|
-
<Box
|
|
234
|
-
<
|
|
235
|
-
{
|
|
236
|
-
</
|
|
169
|
+
<Box flexDirection="row" height={1}>
|
|
170
|
+
<Box width={BADGE_INDENT} flexDirection="row">
|
|
171
|
+
{badge && <CommandBarRowBadge text={badge.text} tone={badge.tone} width={BADGE_COLUMN_WIDTH} />}
|
|
172
|
+
</Box>
|
|
173
|
+
<Box width={labelColumnWidth}>
|
|
174
|
+
<Text fg={isSelected ? paletteSelectedText : presentation.primaryMuted ? paletteSubtleText : paletteText}>
|
|
175
|
+
{label}
|
|
176
|
+
</Text>
|
|
177
|
+
</Box>
|
|
178
|
+
<Box width={trailingWidth}>
|
|
179
|
+
<Text
|
|
180
|
+
fg={isSelected
|
|
181
|
+
? paletteSelectedText
|
|
182
|
+
: presentation.trailingAccent
|
|
183
|
+
? paletteAccentText
|
|
184
|
+
: paletteSubtleText}
|
|
185
|
+
>
|
|
186
|
+
{trailing}
|
|
187
|
+
</Text>
|
|
188
|
+
</Box>
|
|
237
189
|
</Box>
|
|
238
|
-
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
190
|
+
{lines.map((segments, index) => (
|
|
191
|
+
<Box
|
|
192
|
+
key={`line:${index}`}
|
|
193
|
+
flexDirection="row"
|
|
194
|
+
height={1}
|
|
195
|
+
width={lineWidth}
|
|
196
|
+
marginLeft={BADGE_INDENT}
|
|
197
|
+
overflow="hidden"
|
|
245
198
|
>
|
|
246
|
-
{
|
|
247
|
-
|
|
248
|
-
|
|
199
|
+
{segments.map((segment, segmentIndex) => (
|
|
200
|
+
<Text
|
|
201
|
+
key={segmentIndex}
|
|
202
|
+
fg={resolveLineSegmentColor(segment, {
|
|
203
|
+
isSelected,
|
|
204
|
+
paletteHeadingText,
|
|
205
|
+
paletteMatchText,
|
|
206
|
+
paletteSelectedText,
|
|
207
|
+
paletteSubtleText,
|
|
208
|
+
})}
|
|
209
|
+
attributes={segment.emphasis === "match" ? TextAttributes.BOLD : TextAttributes.NONE}
|
|
210
|
+
>
|
|
211
|
+
{segment.text}
|
|
212
|
+
</Text>
|
|
213
|
+
))}
|
|
214
|
+
</Box>
|
|
215
|
+
))}
|
|
249
216
|
</Box>
|
|
250
217
|
);
|
|
251
218
|
});
|
|
252
219
|
|
|
220
|
+
/**
|
|
221
|
+
* A tag set flush against the label edge in a column padded to the widest tag
|
|
222
|
+
* in the list, so the labels line up and the tags share one right edge. Text
|
|
223
|
+
* only: a filled box would outweigh the label it introduces.
|
|
224
|
+
*/
|
|
225
|
+
function CommandBarRowBadge({ text, tone, width }: { text: string; tone: CommandBarBadgeTone; width: number }) {
|
|
226
|
+
const themeColors = useThemeColors();
|
|
227
|
+
return (
|
|
228
|
+
<Box width={width} height={1}>
|
|
229
|
+
<Text fg={commandBarBadgeText(tone, themeColors)}>
|
|
230
|
+
{truncateText(text, width).padStart(width, " ")}
|
|
231
|
+
</Text>
|
|
232
|
+
</Box>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Matched runs keep their highlight on the selected row: the selection colour is
|
|
238
|
+
* what tells you where you are, the match colour is what you were looking for.
|
|
239
|
+
* A muted run (a source lead-in, an ellipsis) steps down one more level than
|
|
240
|
+
* the snippet so it reads as metadata, except on the selected row where the
|
|
241
|
+
* whole line takes the selection text so nothing there goes dim.
|
|
242
|
+
*/
|
|
243
|
+
function resolveLineSegmentColor(
|
|
244
|
+
segment: CommandBarResultLineSegment,
|
|
245
|
+
palette: {
|
|
246
|
+
isSelected: boolean;
|
|
247
|
+
paletteHeadingText: string;
|
|
248
|
+
paletteMatchText: string;
|
|
249
|
+
paletteSelectedText: string;
|
|
250
|
+
paletteSubtleText: string;
|
|
251
|
+
},
|
|
252
|
+
): string {
|
|
253
|
+
if (segment.emphasis === "match") return palette.paletteMatchText;
|
|
254
|
+
if (palette.isSelected) return palette.paletteSelectedText;
|
|
255
|
+
return segment.emphasis === "muted" ? palette.paletteHeadingText : palette.paletteSubtleText;
|
|
256
|
+
}
|
|
257
|
+
|
|
253
258
|
interface CommandBarListBodyProps {
|
|
254
259
|
visibleListState: ListScreenState;
|
|
255
260
|
nativeListRows: CommandBarListRow[];
|
|
@@ -262,6 +267,7 @@ interface CommandBarListBodyProps {
|
|
|
262
267
|
paletteBg: string;
|
|
263
268
|
paletteHeadingText: string;
|
|
264
269
|
paletteHoverBg: string;
|
|
270
|
+
paletteMatchText: string;
|
|
265
271
|
paletteSelectedBg: string;
|
|
266
272
|
paletteSelectedText: string;
|
|
267
273
|
paletteSubtleText: string;
|
|
@@ -286,6 +292,7 @@ export const CommandBarListBody = memo(function CommandBarListBody({
|
|
|
286
292
|
paletteBg,
|
|
287
293
|
paletteHeadingText,
|
|
288
294
|
paletteHoverBg,
|
|
295
|
+
paletteMatchText,
|
|
289
296
|
paletteSelectedBg,
|
|
290
297
|
paletteSelectedText,
|
|
291
298
|
paletteSubtleText,
|
|
@@ -297,12 +304,19 @@ export const CommandBarListBody = memo(function CommandBarListBody({
|
|
|
297
304
|
onListScroll,
|
|
298
305
|
onRowMouseDown,
|
|
299
306
|
}: CommandBarListBodyProps) {
|
|
307
|
+
// Headings, messages and the spinner sit on the label edge: the badge column
|
|
308
|
+
// is a gutter for the rows, not an indent for everything else.
|
|
309
|
+
const labelEdgePadding = contentPadding + BADGE_INDENT;
|
|
310
|
+
const labelEdgeWidth = Math.max(1, queryDisplayWidth - BADGE_INDENT);
|
|
300
311
|
const visibleRows = useMemo(() => {
|
|
301
312
|
const rows = nativeListRows;
|
|
302
313
|
if (nativePaneChrome) return rows;
|
|
303
314
|
const paddedRows = [...rows];
|
|
304
|
-
|
|
315
|
+
// Padded in lines, not rows: a multi-line result already fills several.
|
|
316
|
+
let filledLines = getListRowsHeight(rows);
|
|
317
|
+
while (filledLines < listBodyHeight) {
|
|
305
318
|
paddedRows.push({ kind: "filler", id: `filler:${paddedRows.length}` });
|
|
319
|
+
filledLines += 1;
|
|
306
320
|
}
|
|
307
321
|
return paddedRows;
|
|
308
322
|
}, [
|
|
@@ -319,23 +333,23 @@ export const CommandBarListBody = memo(function CommandBarListBody({
|
|
|
319
333
|
}
|
|
320
334
|
if (row.kind === "spinner") {
|
|
321
335
|
return (
|
|
322
|
-
<Box key={row.id} height={1}
|
|
336
|
+
<Box key={row.id} height={1} paddingLeft={labelEdgePadding} paddingRight={contentPadding} {...(!nativePaneChrome ? { onMouseScroll: onListScroll } : {})}>
|
|
323
337
|
<Spinner label={t(row.label)} />
|
|
324
338
|
</Box>
|
|
325
339
|
);
|
|
326
340
|
}
|
|
327
341
|
if (row.kind === "message") {
|
|
328
342
|
return (
|
|
329
|
-
<Box key={row.id} height={1}
|
|
330
|
-
<Text fg={paletteText}>{truncateText(t(row.label),
|
|
343
|
+
<Box key={row.id} height={1} paddingLeft={labelEdgePadding} paddingRight={contentPadding} {...(!nativePaneChrome ? { onMouseScroll: onListScroll } : {})}>
|
|
344
|
+
<Text fg={paletteText}>{truncateText(t(row.label), labelEdgeWidth)}</Text>
|
|
331
345
|
</Box>
|
|
332
346
|
);
|
|
333
347
|
}
|
|
334
348
|
if (row.kind === "heading") {
|
|
335
349
|
return (
|
|
336
|
-
<Box key={row.id} height={1}
|
|
350
|
+
<Box key={row.id} height={1} paddingLeft={labelEdgePadding} paddingRight={contentPadding} {...(!nativePaneChrome ? { onMouseScroll: onListScroll } : {})}>
|
|
337
351
|
<Text attributes={TextAttributes.BOLD} fg={row.accent ? paletteAccentText : paletteHeadingText}>
|
|
338
|
-
{truncateText(t(row.label),
|
|
352
|
+
{truncateText(t(row.label), labelEdgeWidth)}
|
|
339
353
|
</Text>
|
|
340
354
|
</Box>
|
|
341
355
|
);
|
|
@@ -360,7 +374,9 @@ export const CommandBarListBody = memo(function CommandBarListBody({
|
|
|
360
374
|
nativePaneChrome={nativePaneChrome}
|
|
361
375
|
paletteAccentText={paletteAccentText}
|
|
362
376
|
paletteBg={paletteBg}
|
|
377
|
+
paletteHeadingText={paletteHeadingText}
|
|
363
378
|
paletteHoverBg={paletteHoverBg}
|
|
379
|
+
paletteMatchText={paletteMatchText}
|
|
364
380
|
paletteSelectedBg={paletteSelectedBg}
|
|
365
381
|
paletteSelectedText={paletteSelectedText}
|
|
366
382
|
paletteSubtleText={paletteSubtleText}
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
type CloseAllFn = (options?: { revertThemePreview?: boolean }) => void;
|
|
36
36
|
type NotifyFn = (body: string, options?: { type?: "info" | "success" | "error" }) => void;
|
|
37
37
|
type OpenModeRouteFn = (
|
|
38
|
-
screen: "ticker-search" | "
|
|
38
|
+
screen: "ticker-search" | "layout",
|
|
39
39
|
initialQuery?: string,
|
|
40
40
|
payload?: Record<string, unknown>,
|
|
41
41
|
) => void;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Box, Text, TextAttributes } from "../../../ui";
|
|
2
|
+
import { commandBarMatchText } from "../../../theme/colors";
|
|
2
3
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
3
4
|
import { Button, Spinner } from "../../ui";
|
|
4
|
-
import {
|
|
5
|
-
CommandBarListBody,
|
|
6
|
-
CommandBarListHeader,
|
|
7
|
-
} from "../list/view";
|
|
5
|
+
import { CommandBarListBody } from "../list/view";
|
|
8
6
|
import {
|
|
9
7
|
CommandBarMultiSelectBody,
|
|
10
8
|
isMultiSelectPickerRoute,
|
|
@@ -24,7 +22,9 @@ type CommandBarPanelBodyProps = Omit<
|
|
|
24
22
|
| "nativeOccluderRect"
|
|
25
23
|
| "onNativeOccluderChange"
|
|
26
24
|
| "onOverlayClose"
|
|
25
|
+
| "onQueryChange"
|
|
27
26
|
| "panelBounds"
|
|
27
|
+
| "rootGhostSuffix"
|
|
28
28
|
| "selectedScrollRowIndex"
|
|
29
29
|
| "termHeight"
|
|
30
30
|
| "termWidth"
|
|
@@ -39,6 +39,7 @@ export function CommandBarPanelBody({
|
|
|
39
39
|
contentPadding,
|
|
40
40
|
currentRoute,
|
|
41
41
|
getWorkflowInputRef,
|
|
42
|
+
hasChromeRow,
|
|
42
43
|
labelWidth,
|
|
43
44
|
listBodyHeight,
|
|
44
45
|
nativeListRows,
|
|
@@ -57,15 +58,12 @@ export function CommandBarPanelBody({
|
|
|
57
58
|
onMultiSelectSelect,
|
|
58
59
|
onMultiSelectToggle,
|
|
59
60
|
onNativeSelectRef,
|
|
60
|
-
onQueryChange,
|
|
61
61
|
onThemeCommit,
|
|
62
62
|
onThemePreview,
|
|
63
63
|
onWorkflowActiveTextareaSync,
|
|
64
64
|
onWorkflowSubmit,
|
|
65
65
|
palette,
|
|
66
66
|
queryDisplayWidth,
|
|
67
|
-
rootGhostSuffix,
|
|
68
|
-
rootQueryLength,
|
|
69
67
|
rootShortcutFeedback,
|
|
70
68
|
themePickerActive,
|
|
71
69
|
themePickerFilter,
|
|
@@ -90,62 +88,51 @@ export function CommandBarPanelBody({
|
|
|
90
88
|
|
|
91
89
|
return (
|
|
92
90
|
<>
|
|
93
|
-
{
|
|
91
|
+
{/* The desktop sheet pads itself in CSS; the terminal spends a row. */}
|
|
92
|
+
{!nativePaneChrome && <Box height={1} />}
|
|
94
93
|
|
|
95
|
-
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
94
|
+
{/* Rows stop at the results column, so a selection bar on a wide window
|
|
95
|
+
does not run on past the text into empty sheet. */}
|
|
96
|
+
<Box
|
|
97
|
+
key={bodySlotKey}
|
|
98
|
+
flexDirection="column"
|
|
99
|
+
flexGrow={1}
|
|
100
|
+
width={queryDisplayWidth + contentPadding * 2}
|
|
101
|
+
backgroundColor={panelBg}
|
|
102
|
+
>
|
|
103
|
+
{/* The query itself is typed in the header prompt. This row only exists
|
|
104
|
+
when it has something to say: the way back from a nested screen, or
|
|
105
|
+
what a typed prefix resolved to. Its height is reserved in
|
|
106
|
+
panel/layout.ts, which is why the render is keyed on the same flag. */}
|
|
107
|
+
{hasChromeRow && (
|
|
108
|
+
<>
|
|
109
|
+
<Box height={1} paddingX={contentPadding} flexDirection="row">
|
|
110
|
+
{currentRoute ? (
|
|
111
|
+
<>
|
|
112
|
+
<Text
|
|
113
|
+
fg={paletteSubtleText}
|
|
114
|
+
onMouseDown={(event: any) => {
|
|
115
|
+
event.stopPropagation?.();
|
|
116
|
+
event.preventDefault?.();
|
|
117
|
+
onBack();
|
|
118
|
+
}}
|
|
119
|
+
data-gloom-interactive="true"
|
|
120
|
+
>
|
|
121
|
+
{`\u2190 ${t("Back")}`}
|
|
122
|
+
</Text>
|
|
123
|
+
<Box width={2} />
|
|
124
|
+
<Text fg={paletteText} attributes={TextAttributes.BOLD}>
|
|
125
|
+
{truncateText(t(getCommandBarPanelTitle(currentRoute)), Math.max(1, queryDisplayWidth - 8))}
|
|
126
|
+
</Text>
|
|
127
|
+
</>
|
|
128
|
+
) : rootShortcutFeedback ? (
|
|
129
|
+
<Text fg={paletteSubtleText}>
|
|
130
|
+
{truncateText(rootShortcutFeedback, queryDisplayWidth)}
|
|
131
|
+
</Text>
|
|
132
|
+
) : null}
|
|
105
133
|
</Box>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<Text fg={paletteText} attributes={TextAttributes.BOLD}>
|
|
109
|
-
{t(getCommandBarPanelTitle(currentRoute))}
|
|
110
|
-
</Text>
|
|
111
|
-
</Box>
|
|
112
|
-
</Box>
|
|
113
|
-
)}
|
|
114
|
-
|
|
115
|
-
<Box key={bodySlotKey} flexDirection="column" flexGrow={1} width="100%" backgroundColor={panelBg}>
|
|
116
|
-
{nativePaneChrome && currentRoute && (
|
|
117
|
-
<Box height={1} paddingX={contentPadding}>
|
|
118
|
-
<Text
|
|
119
|
-
fg={paletteSubtleText}
|
|
120
|
-
onMouseDown={(event: any) => {
|
|
121
|
-
event.stopPropagation?.();
|
|
122
|
-
event.preventDefault?.();
|
|
123
|
-
onBack();
|
|
124
|
-
}}
|
|
125
|
-
data-gloom-interactive="true"
|
|
126
|
-
>
|
|
127
|
-
{`← ${t("Back")}`}
|
|
128
|
-
</Text>
|
|
129
|
-
</Box>
|
|
130
|
-
)}
|
|
131
|
-
{(visibleListState || currentRoute?.kind === "picker") && visibleListState && (
|
|
132
|
-
<CommandBarListHeader
|
|
133
|
-
kind={visibleListState.kind}
|
|
134
|
-
title={visibleListState.title}
|
|
135
|
-
query={visibleListState.query}
|
|
136
|
-
queryDisplayWidth={queryDisplayWidth}
|
|
137
|
-
nativePaneChrome={nativePaneChrome}
|
|
138
|
-
inputBg={inputBg}
|
|
139
|
-
paletteBg={paletteBg}
|
|
140
|
-
paletteText={paletteText}
|
|
141
|
-
paletteSubtleText={paletteSubtleText}
|
|
142
|
-
cursorColor={themeColors.textBright}
|
|
143
|
-
contentPadding={contentPadding}
|
|
144
|
-
rootGhostSuffix={rootGhostSuffix}
|
|
145
|
-
rootQueryLength={rootQueryLength}
|
|
146
|
-
rootShortcutFeedback={rootShortcutFeedback}
|
|
147
|
-
onQueryChange={onQueryChange}
|
|
148
|
-
/>
|
|
134
|
+
<Box height={1} />
|
|
135
|
+
</>
|
|
149
136
|
)}
|
|
150
137
|
|
|
151
138
|
{themePickerActive && (
|
|
@@ -184,6 +171,7 @@ export function CommandBarPanelBody({
|
|
|
184
171
|
paletteBg={paletteBg}
|
|
185
172
|
paletteHeadingText={paletteHeadingText}
|
|
186
173
|
paletteHoverBg={paletteHoverBg}
|
|
174
|
+
paletteMatchText={commandBarMatchText(themeColors)}
|
|
187
175
|
paletteSelectedBg={paletteSelectedBg}
|
|
188
176
|
paletteSelectedText={paletteSelectedText}
|
|
189
177
|
paletteSubtleText={paletteSubtleText}
|
|
@@ -249,15 +237,13 @@ export function CommandBarPanelBody({
|
|
|
249
237
|
)}
|
|
250
238
|
</Box>
|
|
251
239
|
|
|
252
|
-
{!nativePaneChrome && <Box
|
|
240
|
+
{!nativePaneChrome && <Box height={1} />}
|
|
253
241
|
</>
|
|
254
242
|
);
|
|
255
243
|
}
|
|
256
244
|
|
|
257
|
-
function getCommandBarPanelTitle(route: CommandBarRoute
|
|
258
|
-
if (!route) return "Commands";
|
|
245
|
+
function getCommandBarPanelTitle(route: CommandBarRoute): string {
|
|
259
246
|
if (route.kind === "mode") {
|
|
260
|
-
if (route.screen === "plugins") return "Manage Plugins";
|
|
261
247
|
if (route.screen === "layout") return "Layout Actions";
|
|
262
248
|
return "Security Description";
|
|
263
249
|
}
|