gloomberb 0.10.1 → 0.10.3
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/package.json +8 -1
- package/src/api-client/auth.ts +1 -0
- package/src/api-client/index.test.ts +359 -108
- package/src/api-client/index.ts +24 -13
- package/src/api-client/socket.ts +70 -35
- package/src/api-client/types.ts +1 -1
- package/src/app/language-observer.test.tsx +82 -0
- package/src/app/language-observer.tsx +13 -0
- package/src/app/pane-runtime/index.tsx +2 -2
- package/src/app/pane-runtime/pane-settings-runtime.tsx +2 -2
- package/src/app/pane-runtime/pane-template-runtime.ts +2 -2
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +2 -2
- package/src/app/runtime/broker-import.ts +2 -2
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +2 -2
- package/src/app.tsx +16 -7
- package/src/brokers/account-cache.ts +6 -6
- package/src/brokers/broker-ticker-sync.ts +3 -3
- package/src/brokers/remote-broker-adapter.ts +2 -2
- package/src/brokers/sync-broker-instance.ts +5 -6
- package/src/cli/commands/api.ts +3 -6
- package/src/cli/commands/automation.ts +7 -15
- package/src/cli/commands/market.ts +26 -61
- package/src/cli/commands/overview.ts +34 -45
- package/src/cli/commands/search.ts +25 -27
- package/src/cli/commands/system.ts +27 -57
- package/src/cli/commands/ticker.ts +62 -63
- package/src/cli/context.test.ts +63 -0
- package/src/cli/context.ts +15 -1
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/data.ts +2 -19
- package/src/cli/pane-functions/index.ts +26 -25
- package/src/cli/pane-functions/report.ts +1 -1
- package/src/cli/pane-functions/screenshot.ts +3 -3
- package/src/cli/scoped-context.ts +41 -0
- package/src/components/chart/composite/composite-chart.test.tsx +615 -18
- package/src/components/chart/composite/composite-chart.tsx +179 -79
- package/src/components/chart/composite/format.test.ts +20 -7
- package/src/components/chart/composite/index.ts +0 -21
- package/src/components/chart/composite/interactions.test.ts +90 -3
- package/src/components/chart/composite/interactions.ts +189 -24
- package/src/components/chart/composite/price-series.ts +0 -2
- package/src/components/chart/composite/rasterizer.ts +10 -9
- package/src/components/chart/composite/renderers.test.ts +108 -2
- package/src/components/chart/composite/scene.test.ts +36 -0
- package/src/components/chart/composite/scene.ts +5 -2
- package/src/components/chart/composite/text-renderer.ts +37 -25
- package/src/components/chart/composite/time-axis.test.ts +243 -0
- package/src/components/chart/composite/time-axis.ts +608 -0
- package/src/components/chart/composite/types.ts +12 -1
- package/src/components/chart/core/data.ts +2 -159
- package/src/components/chart/core/date-window.ts +6 -225
- package/src/components/chart/core/palette.ts +1 -12
- package/src/components/chart/core/pointer.ts +0 -142
- package/src/components/chart/core/types.ts +1 -58
- package/src/components/chart/cursor-motion.ts +2 -4
- package/src/components/chart/indicators/types.ts +0 -9
- package/src/components/chart/market-session.ts +0 -11
- package/src/components/chart/native/kitty/protocol.ts +1 -1
- package/src/components/chart/native/raster/layout.ts +3 -10
- package/src/components/chart/static/chart/axis-overlays.test.tsx +64 -0
- package/src/components/chart/static/chart/axis-overlays.tsx +59 -14
- package/src/components/chart/static/chart/surface.tsx +1 -2
- package/src/components/command-bar/action-runtime.ts +2 -2
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +2 -2
- package/src/components/command-bar/panel/index.tsx +11 -9
- package/src/components/command-bar/routes/ticker-search/actions.ts +2 -2
- package/src/components/command-bar/surface/index.tsx +2 -2
- package/src/components/command-bar/workflow/body.tsx +3 -3
- package/src/components/command-bar/workflow/collection-actions.ts +2 -2
- package/src/components/command-bar/workflow/coordinator.ts +2 -2
- package/src/components/command-bar/workflow/field-row.tsx +25 -11
- package/src/components/command-bar/workflow/tickers.ts +2 -2
- package/src/components/feed-data-table/stack-view.test.tsx +28 -36
- package/src/components/feed-data-table/stack-view.tsx +3 -1
- package/src/components/index.ts +1 -1
- package/src/components/layout/detached-pane-shell.tsx +6 -6
- package/src/components/layout/header.tsx +13 -9
- package/src/components/layout/pane/content.test.tsx +42 -3
- package/src/components/layout/pane/content.tsx +3 -1
- package/src/components/layout/pane/footer/index.test.tsx +45 -2
- package/src/components/layout/pane/footer/registration.tsx +3 -1
- package/src/components/layout/shell/index.tsx +1 -2
- package/src/components/layout/shell/native/surfaces.ts +1 -1
- package/src/components/layout/shell/native/window-state.ts +1 -1
- package/src/components/layout/status-bar.tsx +12 -8
- package/src/components/layout/window-controls.tsx +8 -6
- package/src/components/onboarding/onboarding-wizard.tsx +3 -1
- package/src/components/pane-settings-dialog/desktop.tsx +0 -2
- package/src/components/pane-settings-dialog.tsx +0 -2
- package/src/components/pane-template-wizard.tsx +10 -9
- package/src/components/price-performance.tsx +2 -113
- package/src/components/price-sparkline/model.ts +15 -17
- package/src/components/price-sparkline/view.tsx +8 -7
- package/src/components/speedometer-gauge/desktop.tsx +2 -1
- package/src/components/speedometer-gauge/index.tsx +0 -2
- package/src/components/speedometer-gauge/terminal.tsx +24 -5
- package/src/components/ticker/badge/index.tsx +1 -18
- package/src/components/ui/data-table/index.tsx +1 -0
- package/src/components/ui/data-table/opentui/index.tsx +47 -5
- package/src/components/ui/data-table/types.ts +10 -0
- package/src/components/ui/data-table/visible-range.test.ts +29 -0
- package/src/components/ui/data-table/visible-range.ts +21 -0
- package/src/components/ui/frame.tsx +1 -2
- package/src/components/ui/page-stack-view.test.tsx +126 -0
- package/src/components/ui/page-stack-view.tsx +24 -12
- package/src/components/ui/tabs.tsx +7 -3
- package/src/components/ui/ui.test.tsx +46 -3
- package/src/components/use-external-link-footer.ts +4 -2
- package/src/core/app-service-ports.ts +46 -0
- package/src/core/app-services.test.ts +66 -0
- package/src/core/app-services.ts +17 -15
- package/src/data/config/chart-settings.ts +3 -10
- package/src/data/config/store/index.test.ts +99 -2
- package/src/data/config/store/migrations.ts +278 -0
- package/src/data/config/store/normalize.ts +44 -186
- package/src/data/resource-store.ts +73 -12
- package/src/data/sqlite/cache.test.ts +104 -15
- package/src/i18n/index.test.ts +17 -0
- package/src/i18n/index.ts +23 -6
- package/src/i18n/ja.ts +15 -0
- package/src/i18n/ko.ts +15 -0
- package/src/i18n/react.ts +6 -0
- package/src/i18n/zh-cn.ts +15 -0
- package/src/i18n/zh-tw.ts +15 -0
- package/src/market-data/coordinator/auxiliary.ts +7 -3
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/index.test.ts +26 -0
- package/src/market-data/coordinator/index.ts +12 -6
- package/src/market-data/coordinator/quotes.ts +5 -40
- package/src/market-data/coordinator/subscriptions.test.ts +128 -1
- package/src/market-data/hooks.tsx +47 -1
- package/src/market-data/market/status.ts +6 -6
- package/src/market-data/performance.ts +1 -1
- package/src/market-data/quote-subscription-target.test.ts +37 -0
- package/src/market-data/quote-subscription-target.ts +60 -0
- package/src/market-data/quotes/freshness.ts +1 -0
- package/src/market-data/quotes/resolution.ts +4 -0
- package/src/market-data/request-types.ts +3 -3
- package/src/news/aggregator.test.ts +97 -1
- package/src/news/aggregator.ts +100 -57
- package/src/news/hooks.test.tsx +64 -0
- package/src/news/hooks.ts +18 -25
- package/src/plugins/builtin/account-management/footer.ts +4 -2
- package/src/plugins/builtin/account-management/pane.tsx +9 -4
- package/src/plugins/builtin/ai/agent-history.ts +11 -7
- package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +0 -5
- package/src/plugins/builtin/ai/ask-ai.test.tsx +3 -4
- package/src/plugins/builtin/ai/index.test.ts +2 -2
- package/src/plugins/builtin/ai/index.tsx +10 -11
- package/src/plugins/builtin/ai/pane-settings.ts +1 -1
- package/src/plugins/builtin/ai/pi/runtime.ts +6 -5
- package/src/plugins/builtin/ai/providers.ts +1 -9
- package/src/plugins/builtin/ai/runner.ts +0 -6
- package/src/plugins/builtin/ai/screener/footer.ts +4 -1
- package/src/plugins/builtin/ai/screener/pane.test.tsx +9 -9
- package/src/plugins/builtin/ai/workspace/model.ts +2 -27
- package/src/plugins/builtin/ai/workspace/pane.tsx +2 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +3 -2
- package/src/plugins/builtin/broker-manager/index.tsx +4 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +643 -0
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +134 -0
- package/src/plugins/builtin/chart-composer/editor/model.test.ts +85 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +292 -0
- package/src/plugins/builtin/chart-composer/editor/opentui-view.tsx +108 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +65 -947
- package/src/plugins/builtin/chart-composer/index.tsx +0 -6
- package/src/plugins/builtin/chart-composer/pane.tsx +69 -36
- package/src/plugins/builtin/chart-composer/presets.ts +1 -19
- package/src/plugins/builtin/chart-composer/settings.ts +1 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +1 -1
- package/src/plugins/builtin/chat/content/shortcuts.ts +0 -1
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/persistence.ts +2 -0
- package/src/plugins/builtin/chat/controller/session.test.ts +25 -0
- package/src/plugins/builtin/chat/controller/session.ts +2 -0
- package/src/plugins/builtin/chat/controller/state.ts +7 -0
- package/src/plugins/builtin/chat/controller.test.ts +73 -20
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -0
- package/src/plugins/builtin/cloud-tweets/footer.ts +9 -28
- package/src/plugins/builtin/cloud-tweets/pane.tsx +0 -5
- package/src/plugins/builtin/cloud-tweets/table.tsx +12 -17
- package/src/plugins/builtin/correlation/compute.ts +4 -10
- package/src/plugins/builtin/econ/index.tsx +17 -19
- package/src/plugins/builtin/holders/types.ts +0 -1
- package/src/plugins/builtin/insider/index.tsx +6 -31
- package/src/plugins/builtin/news/index.tsx +5 -7
- package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +6 -8
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -11
- package/src/plugins/builtin/news/wire/read-state.test.ts +7 -0
- package/src/plugins/builtin/news/wire/read-state.ts +18 -28
- package/src/plugins/builtin/news/wire/rss/parser.ts +1 -11
- package/src/plugins/builtin/options/footer.test.ts +127 -0
- package/src/plugins/builtin/options/footer.ts +125 -0
- package/src/plugins/builtin/options/live-quotes.test.ts +341 -0
- package/src/plugins/builtin/options/live-quotes.ts +201 -0
- package/src/plugins/builtin/options/view.test.tsx +74 -1
- package/src/plugins/builtin/options/view.tsx +76 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +103 -117
- package/src/plugins/builtin/portfolio-list/cli/render.ts +11 -5
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -135
- package/src/plugins/builtin/portfolio-list/header.tsx +9 -4
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +4 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +24 -52
- package/src/plugins/builtin/sec/filing-content.test.ts +41 -0
- package/src/plugins/builtin/sec/filing-content.ts +94 -0
- package/src/plugins/builtin/sec/index.tsx +21 -104
- package/src/plugins/builtin/sectors/sector-model.ts +1 -7
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -0
- package/src/plugins/builtin/shared/pane-footer.ts +82 -0
- package/src/plugins/builtin/shared/read-state.ts +64 -3
- package/src/plugins/builtin/substack/read-state.ts +16 -41
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -73
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +10 -10
- package/src/plugins/builtin/yield-curve/index.tsx +11 -9
- package/src/plugins/ibkr/dialogs.tsx +3 -3
- package/src/plugins/ibkr/gateway/fundamentals.ts +1 -1
- package/src/plugins/ibkr/gateway/history-requests.ts +2 -2
- package/src/plugins/ibkr/gateway/history.ts +2 -2
- package/src/plugins/ibkr/gateway/selection.ts +2 -2
- package/src/plugins/ibkr/gateway/service/index.ts +2 -2
- package/src/plugins/ibkr/gateway/service/native.ts +2 -2
- package/src/plugins/plugin-persistence.ts +3 -4
- package/src/plugins/prediction-markets/controller/keyboard.ts +1 -1
- package/src/plugins/prediction-markets/controller/live-updates.ts +6 -5
- package/src/plugins/prediction-markets/detail/book.tsx +2 -2
- package/src/plugins/prediction-markets/detail/outcomes.tsx +3 -1
- package/src/plugins/prediction-markets/detail/pane.tsx +3 -1
- package/src/plugins/prediction-markets/detail/trades.tsx +3 -3
- package/src/plugins/registry/context.ts +3 -4
- package/src/plugins/registry/index.ts +5 -6
- package/src/react/input.test.ts +126 -3
- package/src/react/input.ts +120 -1
- package/src/remote/app-host.tsx +2 -13
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +44 -60
- package/src/renderers/electrobun/bun/desktop/capability-bridge.ts +15 -13
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +26 -22
- package/src/renderers/electrobun/bun/desktop/http-fetch.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/media.ts +5 -3
- package/src/renderers/electrobun/bun/desktop/plugin-state.ts +21 -22
- package/src/renderers/electrobun/bun/desktop/window-controls.ts +3 -1
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +18 -18
- package/src/renderers/electrobun/bun/index.ts +123 -83
- package/src/renderers/electrobun/shared/protocol.ts +146 -7
- package/src/renderers/electrobun/view/app-services.ts +5 -8
- package/src/renderers/electrobun/view/backend-rpc.ts +18 -8
- package/src/renderers/electrobun/view/broker-remote-client.ts +2 -2
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +5 -22
- package/src/renderers/electrobun/view/config-host.ts +1 -1
- package/src/renderers/electrobun/view/context-menu.ts +1 -17
- package/src/renderers/electrobun/view/data-table/index.tsx +44 -4
- package/src/renderers/electrobun/view/data-table/row.tsx +0 -4
- package/src/renderers/electrobun/view/desktop/control-styles.ts +37 -34
- package/src/renderers/electrobun/view/desktop/controls.tsx +36 -33
- package/src/renderers/electrobun/view/desktop/list-view.tsx +15 -12
- package/src/renderers/electrobun/view/desktop/popover.tsx +2 -3
- package/src/renderers/electrobun/view/dialog-host.tsx +2 -3
- package/src/renderers/electrobun/view/fatal-screen.tsx +0 -1
- package/src/renderers/electrobun/view/host/box.tsx +0 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/input.tsx +0 -1
- package/src/renderers/electrobun/view/host/media-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/native.ts +0 -1
- package/src/renderers/electrobun/view/host/scroll-box.tsx +0 -1
- package/src/renderers/electrobun/view/host/tabs.tsx +0 -1
- package/src/renderers/electrobun/view/host/text.tsx +0 -1
- package/src/renderers/electrobun/view/http-fetch.ts +3 -11
- package/src/renderers/electrobun/view/input-host.tsx +10 -53
- package/src/renderers/electrobun/view/key-event.ts +0 -1
- package/src/renderers/electrobun/view/main.tsx +3 -3
- package/src/renderers/electrobun/view/native-renderer.ts +0 -1
- package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +13 -1
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +6 -44
- package/src/renderers/electrobun/view/remote/persistence.ts +6 -2
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.test.ts +86 -0
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +72 -0
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +2 -2
- package/src/renderers/electrobun/view/toast-host.tsx +0 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -2
- package/src/renderers/electrobun/view/update-host.ts +1 -1
- package/src/renderers/opentui/chart-surface.tsx +2 -1
- package/src/renderers/opentui/dialog-host.tsx +20 -4
- package/src/renderers/opentui/image/loader.ts +12 -2
- package/src/renderers/opentui/input-host.tsx +7 -49
- package/src/renderers/opentui/start.tsx +2 -0
- package/src/sources/gloomberb-cloud/history-quality.ts +44 -0
- package/src/sources/gloomberb-cloud/index.test.ts +173 -0
- package/src/sources/gloomberb-cloud/index.ts +42 -20
- package/src/sources/gloomberb-cloud/normalizers.ts +9 -3
- package/src/sources/provider-router/cache.ts +1 -1
- package/src/sources/provider-router/document-routes.ts +10 -5
- package/src/sources/provider-router/financials.test.ts +14 -0
- package/src/sources/provider-router/financials.ts +6 -1
- package/src/sources/provider-router/history.test.ts +163 -1
- package/src/sources/provider-router/history.ts +278 -347
- package/src/sources/provider-router/index.ts +2 -2
- package/src/sources/provider-router/routing.test.ts +39 -0
- package/src/sources/provider-router/routing.ts +24 -11
- package/src/sources/provider-router/supplemental.ts +37 -17
- package/src/sources/sec-edgar/content.ts +2 -12
- package/src/sources/sec-edgar.ts +2 -13
- package/src/sources/yahoo-finance/history.ts +2 -2
- package/src/sources/yahoo-finance/options.ts +5 -0
- package/src/sources/yahoo-finance.ts +2 -2
- package/src/state/app/bootstrap.ts +2 -2
- package/src/state/app/context/index.tsx +2 -2
- package/src/state/hooks/quote-streaming.test.tsx +58 -1
- package/src/state/hooks/quote-streaming.ts +69 -1
- package/src/state/hooks/session-snapshot.ts +2 -2
- package/src/state/selectors.ts +0 -9
- package/src/sync/controller.test.ts +98 -0
- package/src/sync/controller.ts +29 -5
- package/src/sync/react.ts +2 -2
- package/src/sync/types.ts +2 -2
- package/src/theme/colors.test.ts +10 -0
- package/src/theme/colors.ts +75 -78
- package/src/theme/theme-context.test.tsx +67 -0
- package/src/theme/theme-context.tsx +9 -5
- package/src/tickers/open-target.ts +2 -2
- package/src/tickers/search/upsert.ts +2 -2
- package/src/time-series/alignment.ts +0 -7
- package/src/time-series/chart-data.ts +145 -0
- package/src/time-series/date-window.ts +44 -0
- package/src/time-series/history-window.ts +21 -0
- package/src/time-series/hooks.test.ts +59 -0
- package/src/time-series/hooks.ts +33 -12
- package/src/time-series/market-resolution.ts +2 -2
- package/src/time-series/market.ts +1 -1
- package/src/time-series/range.ts +9 -0
- package/src/{components/chart/core → time-series}/resolution.ts +3 -102
- package/src/time-series/resolve.test.ts +203 -1
- package/src/time-series/resolve.ts +96 -18
- package/src/time-series/spec-studies.test.ts +15 -0
- package/src/time-series/spec.ts +2 -2
- package/src/time-series/studies.ts +5 -2
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.test.tsx +358 -0
- package/src/time-series/use-chart-resolution.ts +46 -4
- package/src/types/broker.ts +2 -2
- package/src/types/data-provider.ts +3 -3
- package/src/types/financials.ts +12 -0
- package/src/types/plugin.ts +2 -2
- package/src/ui/context-menu.tsx +3 -2
- package/src/ui/dialog.tsx +2 -2
- package/src/utils/html-entities.ts +3 -5
- package/src/utils/main-thread-monitor.ts +1 -1
- package/src/utils/price-history.ts +5 -5
- package/src/version.ts +3 -1
- package/src/components/chart/core/viewport.test.ts +0 -8
- package/src/components/chart/core/viewport.ts +0 -24
- package/src/time-series/index.ts +0 -14
- /package/src/{components/chart/core → time-series}/resolution.test.ts +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
4
3
|
import {
|
|
@@ -16,7 +15,9 @@ import { measurePerf } from "../../../../utils/perf-marks";
|
|
|
16
15
|
import type {
|
|
17
16
|
DataTableColumn,
|
|
18
17
|
DataTableProps,
|
|
18
|
+
DataTableVisibleRange,
|
|
19
19
|
} from "../../../../components/ui/data-table";
|
|
20
|
+
import { resolveDataTableVisibleRange } from "../../../../components/ui/data-table/visible-range";
|
|
20
21
|
import {
|
|
21
22
|
buildTableGridTemplateColumns,
|
|
22
23
|
getTableWidth,
|
|
@@ -58,6 +59,8 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
58
59
|
onSelect,
|
|
59
60
|
onActivate,
|
|
60
61
|
onTableMouseDown,
|
|
62
|
+
visibleRangeKey,
|
|
63
|
+
onVisibleRangeChange,
|
|
61
64
|
onRowMouseDown,
|
|
62
65
|
onRowContextMenu,
|
|
63
66
|
rowContextMenuSurface = false,
|
|
@@ -81,6 +84,10 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
81
84
|
const dispatch = useAppDispatch();
|
|
82
85
|
const paneInstanceId = usePaneInstance()?.instanceId ?? null;
|
|
83
86
|
const bodyElementRef = useRef<HTMLDivElement | null>(null);
|
|
87
|
+
const lastVisibleRangeRef = useRef<{
|
|
88
|
+
key: string | number | undefined;
|
|
89
|
+
range: DataTableVisibleRange;
|
|
90
|
+
} | null>(null);
|
|
84
91
|
const headerHorizontal = useScrollbarState(false);
|
|
85
92
|
const headerVertical = useScrollbarState(false);
|
|
86
93
|
const bodyHorizontal = useScrollbarState(showHorizontalScrollbar);
|
|
@@ -107,10 +114,32 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
107
114
|
dispatch({ type: "FOCUS_PANE", paneId: paneInstanceId });
|
|
108
115
|
}, [dispatch, paneInstanceId]);
|
|
109
116
|
|
|
117
|
+
const emitVisibleRange = useCallback(() => {
|
|
118
|
+
if (!onVisibleRangeChange) return;
|
|
119
|
+
const element = bodyElementRef.current;
|
|
120
|
+
if (!element) return;
|
|
121
|
+
const range = resolveDataTableVisibleRange({
|
|
122
|
+
itemCount: items.length,
|
|
123
|
+
rowSize: WEB_CELL_HEIGHT,
|
|
124
|
+
scrollOffset: element.scrollTop,
|
|
125
|
+
viewportSize: Math.max(0, element.clientHeight - WEB_CELL_HEIGHT),
|
|
126
|
+
});
|
|
127
|
+
const previous = lastVisibleRangeRef.current;
|
|
128
|
+
if (
|
|
129
|
+
previous !== null
|
|
130
|
+
&& previous.key === visibleRangeKey
|
|
131
|
+
&& previous.range.start === range.start
|
|
132
|
+
&& previous.range.end === range.end
|
|
133
|
+
) return;
|
|
134
|
+
lastVisibleRangeRef.current = { key: visibleRangeKey, range };
|
|
135
|
+
onVisibleRangeChange(range);
|
|
136
|
+
}, [items.length, onVisibleRangeChange, visibleRangeKey]);
|
|
110
137
|
const handleBodyScrollActivity = useCallback(() => {
|
|
111
138
|
onBodyScrollActivity();
|
|
112
|
-
|
|
139
|
+
emitVisibleRange();
|
|
140
|
+
}, [emitVisibleRange, onBodyScrollActivity]);
|
|
113
141
|
const scheduleBodyScrollActivity = useRafCallback(handleBodyScrollActivity);
|
|
142
|
+
const scheduleVisibleRangeMeasure = useRafCallback(emitVisibleRange);
|
|
114
143
|
|
|
115
144
|
const rowVirtualizer = useVirtualizer({
|
|
116
145
|
count: items.length,
|
|
@@ -155,12 +184,20 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
155
184
|
|
|
156
185
|
useEffect(() => {
|
|
157
186
|
measureViewportWidth();
|
|
187
|
+
scheduleVisibleRangeMeasure();
|
|
158
188
|
const element = bodyElementRef.current;
|
|
159
189
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
160
|
-
const observer = new ResizeObserver(
|
|
190
|
+
const observer = new ResizeObserver(() => {
|
|
191
|
+
scheduleViewportWidthMeasure();
|
|
192
|
+
scheduleVisibleRangeMeasure();
|
|
193
|
+
});
|
|
161
194
|
observer.observe(element);
|
|
162
195
|
return () => observer.disconnect();
|
|
163
|
-
}, [measureViewportWidth, scheduleViewportWidthMeasure]);
|
|
196
|
+
}, [measureViewportWidth, scheduleViewportWidthMeasure, scheduleVisibleRangeMeasure]);
|
|
197
|
+
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
scheduleVisibleRangeMeasure();
|
|
200
|
+
}, [items.length, scheduleVisibleRangeMeasure, visibleRangeKey]);
|
|
164
201
|
|
|
165
202
|
useEffect(() => {
|
|
166
203
|
if (scrollToIndex == null || items.length === 0) return;
|
|
@@ -169,6 +206,7 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
169
206
|
rowVirtualizer.scrollToIndex(targetIndex, {
|
|
170
207
|
align: scrollToIndexAlign === "center" ? "center" : "auto",
|
|
171
208
|
});
|
|
209
|
+
scheduleVisibleRangeMeasure();
|
|
172
210
|
return;
|
|
173
211
|
}
|
|
174
212
|
const element = bodyElementRef.current;
|
|
@@ -186,12 +224,14 @@ export function WebDataTable<T, C extends DataTableColumn = DataTableColumn>({
|
|
|
186
224
|
if (nextTop !== currentTop) {
|
|
187
225
|
element.scrollTop = nextTop * WEB_CELL_HEIGHT;
|
|
188
226
|
}
|
|
227
|
+
scheduleVisibleRangeMeasure();
|
|
189
228
|
}, [
|
|
190
229
|
items.length,
|
|
191
230
|
rowVirtualizer,
|
|
192
231
|
scrollToIndex,
|
|
193
232
|
scrollToIndexAlign,
|
|
194
233
|
scrollToIndexVersion,
|
|
234
|
+
scheduleVisibleRangeMeasure,
|
|
195
235
|
virtualize,
|
|
196
236
|
]);
|
|
197
237
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
import { memo, type CSSProperties } from "react";
|
|
4
3
|
import { TextAttributes } from "../../../../ui/host";
|
|
5
|
-
import { useThemeColors } from "../../../../theme/theme-context";
|
|
6
4
|
import type {
|
|
7
5
|
DataTableCell,
|
|
8
6
|
DataTableColumn,
|
|
@@ -72,7 +70,6 @@ export function WebDataTableHeader<C extends DataTableColumn>({
|
|
|
72
70
|
sortColumnId: string | null;
|
|
73
71
|
sortDirection: "asc" | "desc";
|
|
74
72
|
}) {
|
|
75
|
-
useThemeColors();
|
|
76
73
|
return (
|
|
77
74
|
<div
|
|
78
75
|
data-gloom-role="data-table-header-row"
|
|
@@ -183,7 +180,6 @@ function WebDataTableRowInner<
|
|
|
183
180
|
rowContextMenuSurface: boolean;
|
|
184
181
|
selected: boolean;
|
|
185
182
|
}) {
|
|
186
|
-
useThemeColors();
|
|
187
183
|
const sectionHeader: DataTableSectionHeader | null =
|
|
188
184
|
renderSectionHeader?.(item, index) ?? null;
|
|
189
185
|
const baseRowStyle: CSSProperties = {
|
|
@@ -1,77 +1,80 @@
|
|
|
1
1
|
import type { ButtonProps } from "../../../../components/ui/button";
|
|
2
|
-
import { blendHex, colors } from "../../../../theme/colors";
|
|
2
|
+
import { blendHex, colors, type ThemeColors } from "../../../../theme/colors";
|
|
3
3
|
|
|
4
4
|
export const CONTROL_RADIUS = 6;
|
|
5
5
|
|
|
6
|
-
export function panelBorder(): string {
|
|
7
|
-
return blendHex(
|
|
6
|
+
export function panelBorder(palette: ThemeColors = colors): string {
|
|
7
|
+
return blendHex(palette.border, palette.borderFocused, 0.18);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function panelFill(): string {
|
|
11
|
-
return blendHex(
|
|
10
|
+
export function panelFill(palette: ThemeColors = colors): string {
|
|
11
|
+
return blendHex(palette.panel, palette.bg, 0.22);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export function subtlePanelFill(): string {
|
|
15
|
-
return blendHex(
|
|
14
|
+
export function subtlePanelFill(palette: ThemeColors = colors): string {
|
|
15
|
+
return blendHex(palette.panel, palette.bg, 0.42);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export function selectedPanelFill(): string {
|
|
19
|
-
return blendHex(
|
|
18
|
+
export function selectedPanelFill(palette: ThemeColors = colors): string {
|
|
19
|
+
return blendHex(palette.selected, palette.bg, 0.42);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export function controlBorderColor(focused = false, active = false): string {
|
|
23
|
-
if (active) return
|
|
24
|
-
if (focused) return blendHex(
|
|
25
|
-
return panelBorder();
|
|
22
|
+
export function controlBorderColor(focused = false, active = false, palette: ThemeColors = colors): string {
|
|
23
|
+
if (active) return palette.borderFocused;
|
|
24
|
+
if (focused) return blendHex(palette.borderFocused, palette.textBright, 0.24);
|
|
25
|
+
return panelBorder(palette);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function controlShadow(active = false): string {
|
|
28
|
+
export function controlShadow(active = false, palette: ThemeColors = colors): string {
|
|
29
29
|
return active
|
|
30
|
-
? `0 0 0 1px ${blendHex(
|
|
31
|
-
: `inset 0 1px 0 ${blendHex(
|
|
30
|
+
? `0 0 0 1px ${blendHex(palette.bg, palette.borderFocused, 0.18)}, inset 0 1px 0 ${blendHex(palette.bg, palette.textBright, 0.06)}`
|
|
31
|
+
: `inset 0 1px 0 ${blendHex(palette.bg, palette.textBright, 0.04)}`;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export function buttonPalette(
|
|
34
|
+
export function buttonPalette(
|
|
35
|
+
props: Pick<ButtonProps, "variant" | "active" | "disabled">,
|
|
36
|
+
palette: ThemeColors = colors,
|
|
37
|
+
) {
|
|
35
38
|
if (props.disabled) {
|
|
36
39
|
return {
|
|
37
|
-
fg:
|
|
38
|
-
bg: subtlePanelFill(),
|
|
39
|
-
border: panelBorder(),
|
|
40
|
+
fg: palette.textMuted,
|
|
41
|
+
bg: subtlePanelFill(palette),
|
|
42
|
+
border: panelBorder(palette),
|
|
40
43
|
};
|
|
41
44
|
}
|
|
42
45
|
if (props.active) {
|
|
43
46
|
return {
|
|
44
|
-
fg:
|
|
45
|
-
bg:
|
|
46
|
-
border:
|
|
47
|
+
fg: palette.selectedText,
|
|
48
|
+
bg: palette.selected,
|
|
49
|
+
border: palette.borderFocused,
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
switch (props.variant) {
|
|
51
54
|
case "primary":
|
|
52
55
|
return {
|
|
53
|
-
fg:
|
|
54
|
-
bg:
|
|
55
|
-
border:
|
|
56
|
+
fg: palette.bg,
|
|
57
|
+
bg: palette.borderFocused,
|
|
58
|
+
border: palette.borderFocused,
|
|
56
59
|
};
|
|
57
60
|
case "danger":
|
|
58
61
|
return {
|
|
59
|
-
fg:
|
|
60
|
-
bg:
|
|
61
|
-
border:
|
|
62
|
+
fg: palette.bg,
|
|
63
|
+
bg: palette.negative,
|
|
64
|
+
border: palette.negative,
|
|
62
65
|
};
|
|
63
66
|
case "ghost":
|
|
64
67
|
return {
|
|
65
|
-
fg:
|
|
68
|
+
fg: palette.textDim,
|
|
66
69
|
bg: "transparent",
|
|
67
|
-
border: panelBorder(),
|
|
70
|
+
border: panelBorder(palette),
|
|
68
71
|
};
|
|
69
72
|
case "secondary":
|
|
70
73
|
default:
|
|
71
74
|
return {
|
|
72
|
-
fg:
|
|
73
|
-
bg: panelFill(),
|
|
74
|
-
border: panelBorder(),
|
|
75
|
+
fg: palette.text,
|
|
76
|
+
bg: panelFill(palette),
|
|
77
|
+
border: panelBorder(palette),
|
|
75
78
|
};
|
|
76
79
|
}
|
|
77
80
|
}
|
|
@@ -3,7 +3,7 @@ import { useRef, type RefObject } from "react";
|
|
|
3
3
|
import { Box, Input, Text, Textarea, editableTextContextMenuItems, useRendererHost, useUiCapabilities } from "../../../../ui";
|
|
4
4
|
import { TextAttributes, type InputRenderable } from "../../../../ui";
|
|
5
5
|
import { useShortcut } from "../../../../react/input";
|
|
6
|
-
import { blendHex,
|
|
6
|
+
import { blendHex, type ThemeColors } from "../../../../theme/colors";
|
|
7
7
|
import { contrastRatio } from "../../../../theme/color-utils";
|
|
8
8
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
9
9
|
import { isDetailBackNavigationKey } from "../../../../utils/back-navigation";
|
|
@@ -35,8 +35,8 @@ export function WebButton({
|
|
|
35
35
|
width,
|
|
36
36
|
height,
|
|
37
37
|
}: ButtonProps) {
|
|
38
|
-
useThemeColors();
|
|
39
|
-
const palette = buttonPalette({ variant, active, disabled });
|
|
38
|
+
const colors = useThemeColors();
|
|
39
|
+
const palette = buttonPalette({ variant, active, disabled }, colors);
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<Box
|
|
@@ -56,7 +56,7 @@ export function WebButton({
|
|
|
56
56
|
borderRadius: CONTROL_RADIUS,
|
|
57
57
|
paddingLeft: 8,
|
|
58
58
|
paddingRight: 8,
|
|
59
|
-
boxShadow: controlShadow(active),
|
|
59
|
+
boxShadow: controlShadow(active, colors),
|
|
60
60
|
cursor: disabled ? "default" : "pointer",
|
|
61
61
|
}}
|
|
62
62
|
>
|
|
@@ -81,7 +81,7 @@ export function WebButton({
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function checkboxAccentColor(): string {
|
|
84
|
+
function checkboxAccentColor(colors: ThemeColors): string {
|
|
85
85
|
const base = colors.borderFocused;
|
|
86
86
|
const nativeCheckmark = "#ffffff";
|
|
87
87
|
const candidates = [
|
|
@@ -112,15 +112,15 @@ export function WebCheckbox({
|
|
|
112
112
|
description,
|
|
113
113
|
width,
|
|
114
114
|
}: CheckboxProps) {
|
|
115
|
-
useThemeColors();
|
|
115
|
+
const colors = useThemeColors();
|
|
116
116
|
const textColor = disabled
|
|
117
117
|
? colors.textMuted
|
|
118
118
|
: active
|
|
119
119
|
? colors.textBright
|
|
120
120
|
: colors.text;
|
|
121
121
|
const visibleLabel = displayLabel ?? label;
|
|
122
|
-
const accentColor = checkboxAccentColor();
|
|
123
|
-
const borderColor = checked ? accentColor : controlBorderColor(active, false);
|
|
122
|
+
const accentColor = checkboxAccentColor(colors);
|
|
123
|
+
const borderColor = checked ? accentColor : controlBorderColor(active, false, colors);
|
|
124
124
|
return (
|
|
125
125
|
<Box
|
|
126
126
|
flexDirection="column"
|
|
@@ -164,7 +164,7 @@ export function WebCheckbox({
|
|
|
164
164
|
width: 14,
|
|
165
165
|
height: 14,
|
|
166
166
|
margin: 0,
|
|
167
|
-
backgroundColor: checked ? accentColor : panelFill(),
|
|
167
|
+
backgroundColor: checked ? accentColor : panelFill(colors),
|
|
168
168
|
backgroundImage: checked ? checkboxCheckImage() : undefined,
|
|
169
169
|
backgroundPosition: "center",
|
|
170
170
|
backgroundRepeat: "no-repeat",
|
|
@@ -217,12 +217,15 @@ export function WebTextField({
|
|
|
217
217
|
hint,
|
|
218
218
|
type = "text",
|
|
219
219
|
variant = "default",
|
|
220
|
-
backgroundColor
|
|
221
|
-
textColor
|
|
222
|
-
placeholderColor
|
|
220
|
+
backgroundColor,
|
|
221
|
+
textColor,
|
|
222
|
+
placeholderColor,
|
|
223
223
|
onMouseDown,
|
|
224
224
|
}: TextFieldProps) {
|
|
225
|
-
useThemeColors();
|
|
225
|
+
const colors = useThemeColors();
|
|
226
|
+
const resolvedBackgroundColor = backgroundColor ?? colors.bg;
|
|
227
|
+
const resolvedTextColor = textColor ?? colors.text;
|
|
228
|
+
const resolvedPlaceholderColor = placeholderColor ?? colors.textDim;
|
|
226
229
|
const localInputRef = useRef<InputRenderable>(null);
|
|
227
230
|
const resolvedInputRef = inputRef ?? localInputRef;
|
|
228
231
|
const renderer = useRendererHost();
|
|
@@ -234,7 +237,7 @@ export function WebTextField({
|
|
|
234
237
|
{label && (
|
|
235
238
|
<Box height={1}>
|
|
236
239
|
<Text
|
|
237
|
-
fg={focused ? colors.textBright :
|
|
240
|
+
fg={focused ? colors.textBright : resolvedPlaceholderColor}
|
|
238
241
|
style={{ fontWeight: 600 }}
|
|
239
242
|
>
|
|
240
243
|
{label}
|
|
@@ -245,7 +248,7 @@ export function WebTextField({
|
|
|
245
248
|
height={1}
|
|
246
249
|
width={width}
|
|
247
250
|
alignItems="center"
|
|
248
|
-
backgroundColor={plain ? "transparent" :
|
|
251
|
+
backgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
249
252
|
onMouseDown={() => {
|
|
250
253
|
onMouseDown?.();
|
|
251
254
|
resolvedInputRef.current?.focus?.();
|
|
@@ -259,9 +262,9 @@ export function WebTextField({
|
|
|
259
262
|
}}
|
|
260
263
|
data-gloom-role="desktop-text-field"
|
|
261
264
|
style={{
|
|
262
|
-
border: plain ? "none" : `1px solid ${controlBorderColor(focused, false)}`,
|
|
265
|
+
border: plain ? "none" : `1px solid ${controlBorderColor(focused, false, colors)}`,
|
|
263
266
|
borderRadius: plain ? 0 : CONTROL_RADIUS,
|
|
264
|
-
boxShadow: plain ? undefined : controlShadow(focused),
|
|
267
|
+
boxShadow: plain ? undefined : controlShadow(focused, colors),
|
|
265
268
|
overflow: "hidden",
|
|
266
269
|
}}
|
|
267
270
|
>
|
|
@@ -272,11 +275,11 @@ export function WebTextField({
|
|
|
272
275
|
type={type}
|
|
273
276
|
placeholder={placeholder}
|
|
274
277
|
focused={focused}
|
|
275
|
-
textColor={
|
|
276
|
-
focusedTextColor={
|
|
277
|
-
placeholderColor={
|
|
278
|
-
backgroundColor={plain ? "transparent" :
|
|
279
|
-
focusedBackgroundColor={plain ? "transparent" :
|
|
278
|
+
textColor={resolvedTextColor}
|
|
279
|
+
focusedTextColor={resolvedTextColor}
|
|
280
|
+
placeholderColor={resolvedPlaceholderColor}
|
|
281
|
+
backgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
282
|
+
focusedBackgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
280
283
|
cursorColor={colors.textBright}
|
|
281
284
|
style={{
|
|
282
285
|
paddingLeft: plain ? 0 : 10,
|
|
@@ -318,7 +321,7 @@ export function WebMessageComposer({
|
|
|
318
321
|
keyBindings,
|
|
319
322
|
wrapText = false,
|
|
320
323
|
}: MessageComposerProps) {
|
|
321
|
-
useThemeColors();
|
|
324
|
+
const colors = useThemeColors();
|
|
322
325
|
const borderColor = focused
|
|
323
326
|
? blendHex(colors.borderFocused, colors.textBright, 0.24)
|
|
324
327
|
: colors.border;
|
|
@@ -336,7 +339,7 @@ export function WebMessageComposer({
|
|
|
336
339
|
flexDirection="row"
|
|
337
340
|
width={width}
|
|
338
341
|
height={height}
|
|
339
|
-
backgroundColor={panelFill()}
|
|
342
|
+
backgroundColor={panelFill(colors)}
|
|
340
343
|
onMouseDown={requestFocus}
|
|
341
344
|
data-gloom-role="desktop-message-composer"
|
|
342
345
|
style={{
|
|
@@ -378,13 +381,13 @@ export function WebSegmentedControl({
|
|
|
378
381
|
value,
|
|
379
382
|
onChange,
|
|
380
383
|
}: SegmentedControlProps) {
|
|
381
|
-
useThemeColors();
|
|
384
|
+
const colors = useThemeColors();
|
|
382
385
|
return (
|
|
383
386
|
<Box
|
|
384
387
|
flexDirection="row"
|
|
385
|
-
backgroundColor={panelFill()}
|
|
388
|
+
backgroundColor={panelFill(colors)}
|
|
386
389
|
style={{
|
|
387
|
-
border: `1px solid ${panelBorder()}`,
|
|
390
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
388
391
|
borderRadius: CONTROL_RADIUS,
|
|
389
392
|
padding: 2,
|
|
390
393
|
}}
|
|
@@ -428,7 +431,7 @@ export function WebDialogFrame({
|
|
|
428
431
|
footer,
|
|
429
432
|
showTitleDivider = false,
|
|
430
433
|
}: DialogFrameProps) {
|
|
431
|
-
useThemeColors();
|
|
434
|
+
const colors = useThemeColors();
|
|
432
435
|
return (
|
|
433
436
|
<Box flexDirection="column" style={{ padding: 14 }}>
|
|
434
437
|
<Box
|
|
@@ -436,7 +439,7 @@ export function WebDialogFrame({
|
|
|
436
439
|
flexDirection="row"
|
|
437
440
|
alignItems="center"
|
|
438
441
|
style={{
|
|
439
|
-
borderBottom: showTitleDivider ? `1px solid ${panelBorder()}` : "none",
|
|
442
|
+
borderBottom: showTitleDivider ? `1px solid ${panelBorder(colors)}` : "none",
|
|
440
443
|
paddingBottom: showTitleDivider ? 8 : 0,
|
|
441
444
|
marginBottom: showTitleDivider ? 10 : 14,
|
|
442
445
|
}}
|
|
@@ -450,7 +453,7 @@ export function WebDialogFrame({
|
|
|
450
453
|
<Box
|
|
451
454
|
height={1}
|
|
452
455
|
style={{
|
|
453
|
-
borderTop: `1px solid ${panelBorder()}`,
|
|
456
|
+
borderTop: `1px solid ${panelBorder(colors)}`,
|
|
454
457
|
paddingTop: 8,
|
|
455
458
|
marginTop: 10,
|
|
456
459
|
}}
|
|
@@ -474,7 +477,7 @@ export function WebPageStackView({
|
|
|
474
477
|
backLabel = "Back",
|
|
475
478
|
backHint,
|
|
476
479
|
}: PageStackViewProps) {
|
|
477
|
-
useThemeColors();
|
|
480
|
+
const colors = useThemeColors();
|
|
478
481
|
useShortcut((event) => {
|
|
479
482
|
if (!focused || !detailOpen || !isDetailBackNavigationKey(event)) return;
|
|
480
483
|
event.stopPropagation?.();
|
|
@@ -506,7 +509,7 @@ export function WebPageStackView({
|
|
|
506
509
|
height={1}
|
|
507
510
|
flexDirection="row"
|
|
508
511
|
alignItems="center"
|
|
509
|
-
backgroundColor={panelFill()}
|
|
512
|
+
backgroundColor={panelFill(colors)}
|
|
510
513
|
onMouseDown={(event: { preventDefault?: () => void; stopPropagation?: () => void }) => {
|
|
511
514
|
event.preventDefault?.();
|
|
512
515
|
event.stopPropagation?.();
|
|
@@ -514,7 +517,7 @@ export function WebPageStackView({
|
|
|
514
517
|
}}
|
|
515
518
|
data-gloom-interactive="true"
|
|
516
519
|
style={{
|
|
517
|
-
border: `1px solid ${panelBorder()}`,
|
|
520
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
518
521
|
borderRadius: CONTROL_RADIUS,
|
|
519
522
|
paddingInline: 8,
|
|
520
523
|
cursor: "pointer",
|
|
@@ -3,7 +3,7 @@ import { useEffect, useRef, useState, type CSSProperties } from "react";
|
|
|
3
3
|
import { Box, ScrollBox, Text, type ScrollBoxRenderable } from "../../../../ui";
|
|
4
4
|
import { TextAttributes } from "../../../../ui";
|
|
5
5
|
import type { ListRowState, ListViewItem, ListViewProps } from "../../../../components/ui/list-view";
|
|
6
|
-
import { blendHex,
|
|
6
|
+
import { blendHex, hoverBg, type ThemeColors } from "../../../../theme/colors";
|
|
7
7
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
8
8
|
import {
|
|
9
9
|
CONTROL_RADIUS,
|
|
@@ -19,6 +19,7 @@ function DefaultDesktopRow({
|
|
|
19
19
|
item: ListViewItem;
|
|
20
20
|
selected: boolean;
|
|
21
21
|
}) {
|
|
22
|
+
const colors = useThemeColors();
|
|
22
23
|
return (
|
|
23
24
|
<Box
|
|
24
25
|
flexDirection="row"
|
|
@@ -50,7 +51,7 @@ function DefaultDesktopRow({
|
|
|
50
51
|
);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
function listRowStyle(selected: boolean): CSSProperties {
|
|
54
|
+
function listRowStyle(selected: boolean, colors: ThemeColors): CSSProperties {
|
|
54
55
|
return {
|
|
55
56
|
borderRadius: CONTROL_RADIUS,
|
|
56
57
|
border: `1px solid ${selected ? colors.borderFocused : "transparent"}`,
|
|
@@ -85,12 +86,12 @@ export function WebListView({
|
|
|
85
86
|
selectOnHover = false,
|
|
86
87
|
autoScrollToIndex = true,
|
|
87
88
|
}: ListViewProps) {
|
|
88
|
-
useThemeColors();
|
|
89
|
+
const colors = useThemeColors();
|
|
89
90
|
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
|
|
90
91
|
const scrollRef = useRef<ScrollBoxRenderable>(null);
|
|
91
92
|
const baseBg = bgColor ?? colors.bg;
|
|
92
|
-
const activeBg = selectedBgColor ?? selectedPanelFill();
|
|
93
|
-
const rowHoverBg = hoverBgColor ?? hoverBg();
|
|
93
|
+
const activeBg = selectedBgColor ?? selectedPanelFill(colors);
|
|
94
|
+
const rowHoverBg = hoverBgColor ?? hoverBg(colors);
|
|
94
95
|
const selectedItem = selectedIndex >= 0 ? items[selectedIndex] : undefined;
|
|
95
96
|
const activeScrollIndex = scrollIndex ?? selectedIndex;
|
|
96
97
|
const effectiveSurface = surface ?? (scrollable ? "framed" : "plain");
|
|
@@ -102,10 +103,10 @@ export function WebListView({
|
|
|
102
103
|
backgroundColor: "transparent",
|
|
103
104
|
}
|
|
104
105
|
: {
|
|
105
|
-
border: `1px solid ${panelBorder()}`,
|
|
106
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
106
107
|
borderRadius: CONTROL_RADIUS,
|
|
107
108
|
padding: 4,
|
|
108
|
-
backgroundColor: subtlePanelFill(),
|
|
109
|
+
backgroundColor: subtlePanelFill(colors),
|
|
109
110
|
};
|
|
110
111
|
|
|
111
112
|
useEffect(() => {
|
|
@@ -113,7 +114,7 @@ export function WebListView({
|
|
|
113
114
|
const scrollBox = scrollRef.current;
|
|
114
115
|
if (!scrollBox) return;
|
|
115
116
|
const safeIndex = Math.min(activeScrollIndex, items.length - 1);
|
|
116
|
-
const viewportHeight = Math.max(scrollBox.viewport
|
|
117
|
+
const viewportHeight = Math.max(scrollBox.viewport?.height ?? 0, 1);
|
|
117
118
|
const rowTop = safeIndex * rowHeight;
|
|
118
119
|
const rowBottom = rowTop + rowHeight;
|
|
119
120
|
if (rowTop < scrollBox.scrollTop) {
|
|
@@ -127,7 +128,9 @@ export function WebListView({
|
|
|
127
128
|
if (!scrollable) return;
|
|
128
129
|
const scrollBox = scrollRef.current;
|
|
129
130
|
if (!scrollBox) return;
|
|
130
|
-
scrollBox.verticalScrollBar
|
|
131
|
+
if (scrollBox.verticalScrollBar) {
|
|
132
|
+
scrollBox.verticalScrollBar.visible = items.length * rowHeight > (scrollBox.viewport?.height ?? 0);
|
|
133
|
+
}
|
|
131
134
|
}, [items.length, height, flexGrow, rowHeight, scrollable]);
|
|
132
135
|
|
|
133
136
|
const rows = items.length === 0
|
|
@@ -163,7 +166,7 @@ export function WebListView({
|
|
|
163
166
|
onActivate?.(item, index);
|
|
164
167
|
}}
|
|
165
168
|
data-gloom-role="desktop-list-row"
|
|
166
|
-
style={listRowStyle(selected)}
|
|
169
|
+
style={listRowStyle(selected, colors)}
|
|
167
170
|
>
|
|
168
171
|
{renderRow
|
|
169
172
|
? renderRow(item, state, index)
|
|
@@ -196,9 +199,9 @@ export function WebListView({
|
|
|
196
199
|
{showSelectedDescription && selectedItem?.description && (
|
|
197
200
|
<Box
|
|
198
201
|
flexDirection="row"
|
|
199
|
-
backgroundColor={subtlePanelFill()}
|
|
202
|
+
backgroundColor={subtlePanelFill(colors)}
|
|
200
203
|
style={{
|
|
201
|
-
border: `1px solid ${panelBorder()}`,
|
|
204
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
202
205
|
borderRadius: CONTROL_RADIUS,
|
|
203
206
|
paddingInline: 10,
|
|
204
207
|
}}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
|
|
4
3
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
5
4
|
import { createPortal } from "react-dom";
|
|
6
5
|
import type { HostPopoverProps } from "../../../../ui";
|
|
7
|
-
import { blendHex
|
|
6
|
+
import { blendHex } from "../../../../theme/colors";
|
|
8
7
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
9
8
|
|
|
10
9
|
const VIEWPORT_MARGIN = 10;
|
|
@@ -31,7 +30,7 @@ export function WebPopover({
|
|
|
31
30
|
maxWidth = "min(420px, calc(100vw - 20px))",
|
|
32
31
|
label,
|
|
33
32
|
}: HostPopoverProps) {
|
|
34
|
-
useThemeColors();
|
|
33
|
+
const colors = useThemeColors();
|
|
35
34
|
const anchorRef = useRef<HTMLDivElement | null>(null);
|
|
36
35
|
const popoverRef = useRef<HTMLDivElement | null>(null);
|
|
37
36
|
const [position, setPosition] = useState<PopoverPosition>({ left: 0, top: 0, visible: false });
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
|
4
3
|
import { DialogHostProvider, type DialogApi } from "../../../ui/dialog";
|
|
5
|
-
import { blendHex
|
|
4
|
+
import { blendHex } from "../../../theme/colors";
|
|
6
5
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
7
6
|
|
|
8
7
|
interface DialogState {
|
|
@@ -27,7 +26,7 @@ export function shouldFocusDialogContainer(
|
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
export function WebDialogHostProvider({ children }: { children: ReactNode }) {
|
|
30
|
-
useThemeColors();
|
|
29
|
+
const colors = useThemeColors();
|
|
31
30
|
const [dialogState, setDialogState] = useState<DialogState | null>(null);
|
|
32
31
|
const dialogStateRef = useRef<DialogState | null>(null);
|
|
33
32
|
const dialogElementRef = useRef<HTMLDivElement | null>(null);
|