gloomberb 0.7.0 → 0.7.2
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 +1 -1
- package/src/app.tsx +149 -51
- package/src/capabilities/factories.ts +3 -0
- package/src/components/chart/chart-renderer.ts +24 -12
- package/src/components/chart/chart.test.ts +43 -0
- package/src/components/chart/comparison-chart-renderer.test.ts +26 -0
- package/src/components/chart/comparison-chart-renderer.ts +13 -6
- package/src/components/chart/comparison-stock-chart.tsx +15 -12
- package/src/components/chart/price-axis-labels.tsx +114 -0
- package/src/components/chart/static-chart-surface.tsx +2 -0
- package/src/components/chart/stock-chart.tsx +31 -20
- package/src/components/chart/time-axis-label.tsx +78 -1
- package/src/components/command-bar/__snapshots__/command-bar.test.tsx.snap +0 -28
- package/src/components/command-bar/command-bar.test.tsx +114 -31
- package/src/components/command-bar/command-bar.tsx +587 -335
- package/src/components/command-bar/command-registry.ts +0 -10
- package/src/components/command-bar/helpers.ts +2 -5
- package/src/components/command-bar/list-model.ts +1 -2
- package/src/components/command-bar/theme-picker.tsx +254 -0
- package/src/components/command-bar/view-model.test.ts +4 -4
- package/src/components/command-bar/view-model.ts +1 -1
- package/src/components/command-bar/workflow-types.ts +1 -2
- package/src/components/layout/detached-pane-shell.tsx +29 -10
- package/src/components/layout/floating-pane.tsx +5 -2
- package/src/components/layout/header.tsx +2 -0
- package/src/components/layout/pane-content.test.tsx +64 -0
- package/src/components/layout/pane-content.tsx +2 -0
- package/src/components/layout/pane-sizing.ts +9 -2
- package/src/components/layout/pane-title.ts +4 -1
- package/src/components/layout/pane.tsx +11 -5
- package/src/components/layout/shell.test.tsx +198 -0
- package/src/components/layout/shell.tsx +33 -2
- package/src/components/layout/status-bar.tsx +2 -0
- package/src/components/speedometer-gauge.tsx +29 -25
- package/src/components/table-view-shared.tsx +85 -3
- package/src/components/ticker-list-table-view.tsx +16 -2
- package/src/components/ticker-list-table.test.tsx +82 -1
- package/src/components/ticker-list-table.tsx +22 -9
- package/src/components/ui/data-table.tsx +12 -9
- package/src/components/ui/frame.tsx +2 -0
- package/src/components/ui/table-layout.test.ts +27 -1
- package/src/components/ui/table-layout.ts +39 -1
- package/src/components/ui/tabs.tsx +34 -1
- package/src/components/ui/ui.test.tsx +68 -1
- package/src/core/state/app-state.ts +4 -14
- package/src/market-data/coordinator.test.ts +75 -0
- package/src/market-data/coordinator.ts +218 -48
- package/src/news/aggregator.test.ts +49 -1
- package/src/news/aggregator.ts +48 -0
- package/src/news/hooks.ts +6 -2
- package/src/plugins/builtin/ai/screener-pane.tsx +3 -2
- package/src/plugins/builtin/analytics/index.tsx +1 -18
- package/src/plugins/builtin/chat-controller.test.ts +83 -1
- package/src/plugins/builtin/chat-controller.ts +491 -243
- package/src/plugins/builtin/chat.test.tsx +425 -7
- package/src/plugins/builtin/chat.tsx +1109 -211
- package/src/plugins/builtin/cloud-tweets.tsx +1 -0
- package/src/plugins/builtin/fear-greed/index.tsx +148 -39
- package/src/plugins/builtin/holders/index.test.ts +13 -1
- package/src/plugins/builtin/holders/index.tsx +54 -14
- package/src/plugins/builtin/market-movers/index.tsx +12 -18
- package/src/plugins/builtin/market-movers/screener.test.ts +39 -1
- package/src/plugins/builtin/market-movers/screener.ts +70 -17
- package/src/plugins/builtin/news-wire/breaking-pane.tsx +3 -2
- package/src/plugins/builtin/news-wire/industry-pane.tsx +4 -18
- package/src/plugins/builtin/news-wire/news-detail-view.tsx +46 -4
- package/src/plugins/builtin/news-wire/news-preset-pane.tsx +3 -2
- package/src/plugins/builtin/notes.tsx +1 -0
- package/src/plugins/builtin/options.tsx +2 -16
- package/src/plugins/builtin/portfolio-list/pane.tsx +16 -39
- package/src/plugins/builtin/research/index.test.ts +94 -0
- package/src/plugins/builtin/research/index.tsx +159 -12
- package/src/plugins/builtin/ticker-detail/pane.tsx +28 -22
- package/src/plugins/builtin/ticker-detail.test.tsx +38 -0
- package/src/plugins/plugin-runtime.test.tsx +34 -0
- package/src/plugins/plugin-runtime.tsx +7 -2
- package/src/plugins/prediction-markets/controller.ts +0 -15
- package/src/plugins/prediction-markets/detail/pane.tsx +1 -0
- package/src/plugins/registry.ts +3 -3
- package/src/plugins/ticker-navigation.test.ts +66 -0
- package/src/plugins/ticker-navigation.ts +44 -0
- package/src/react/input.ts +1 -1
- package/src/renderers/electrobun/bun/index.ts +32 -11
- package/src/renderers/electrobun/bun/window-focus.ts +37 -0
- package/src/renderers/electrobun/shared/protocol.ts +7 -1
- package/src/renderers/electrobun/view/app-services.ts +88 -31
- package/src/renderers/electrobun/view/backend-rpc.ts +15 -0
- package/src/renderers/electrobun/view/data-table.tsx +111 -96
- package/src/renderers/electrobun/view/desktop-controls.tsx +8 -0
- package/src/renderers/electrobun/view/desktop-window-bridge.ts +12 -1
- package/src/renderers/electrobun/view/dialog-host.tsx +2 -0
- package/src/renderers/electrobun/view/input-host.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +18 -1
- package/src/renderers/electrobun/view/styles.css +6 -8
- package/src/renderers/electrobun/view/toast-host.tsx +29 -3
- package/src/renderers/electrobun/view/ui-host.tsx +101 -5
- package/src/renderers/opentui/input-host.tsx +1 -1
- package/src/sources/gloomberb-cloud.test.ts +86 -1
- package/src/sources/gloomberb-cloud.ts +117 -21
- package/src/sources/provider-router.test.ts +122 -0
- package/src/sources/provider-router.ts +198 -11
- package/src/sources/yahoo-finance.test.ts +44 -0
- package/src/sources/yahoo-finance.ts +6 -0
- package/src/state/app-bootstrap.ts +20 -7
- package/src/state/app-context-selector.test.tsx +189 -4
- package/src/state/app-context.test.ts +20 -0
- package/src/state/app-context.tsx +48 -16
- package/src/state/use-inline-tickers.ts +13 -10
- package/src/theme/colors.test.ts +75 -0
- package/src/theme/colors.ts +64 -3
- package/src/theme/theme-context.tsx +26 -0
- package/src/types/capability-route-source.ts +1 -0
- package/src/types/data-provider.ts +15 -1
- package/src/types/desktop-window.ts +6 -0
- package/src/types/financials.ts +2 -0
- package/src/types/plugin.ts +1 -1
- package/src/ui/host.tsx +14 -2
- package/src/ui/index.tsx +1 -0
- package/src/utils/api-client.test.ts +32 -0
- package/src/utils/api-client.ts +119 -18
- package/src/utils/double-escape-close.test.ts +33 -0
- package/src/utils/double-escape-close.ts +40 -0
- package/src/utils/throttled-fetch.test.ts +22 -0
- package/src/utils/throttled-fetch.ts +3 -1
- package/src/utils/ticker-search.ts +53 -9
- package/src/version.ts +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { Box, Text, useUiCapabilities } from "../../ui";
|
|
3
|
+
import { colors } from "../../theme/colors";
|
|
4
|
+
import { formatAxisCell } from "./chart-renderer";
|
|
5
|
+
|
|
6
|
+
interface PriceAxisLabelsProps {
|
|
7
|
+
axisLabels: ReadonlyMap<number, string>;
|
|
8
|
+
axisWidth: number;
|
|
9
|
+
axisSectionWidth: number;
|
|
10
|
+
height: number;
|
|
11
|
+
cursorRow: number | null;
|
|
12
|
+
cursorPixelY?: number | null;
|
|
13
|
+
cursorLabel: string | null;
|
|
14
|
+
cursorColor: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface CursorPriceAxisOverlay {
|
|
18
|
+
labelText: string | null;
|
|
19
|
+
topPercent: number | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function clamp(value: number, min: number, max: number): number {
|
|
23
|
+
return Math.max(min, Math.min(max, value));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function buildCursorPriceAxisOverlay({
|
|
27
|
+
axisWidth,
|
|
28
|
+
axisSectionWidth,
|
|
29
|
+
height,
|
|
30
|
+
cursorPixelY,
|
|
31
|
+
cursorLabel,
|
|
32
|
+
cellHeightPx,
|
|
33
|
+
}: {
|
|
34
|
+
axisWidth: number;
|
|
35
|
+
axisSectionWidth: number;
|
|
36
|
+
height: number;
|
|
37
|
+
cursorPixelY: number | null | undefined;
|
|
38
|
+
cursorLabel: string | null;
|
|
39
|
+
cellHeightPx: number;
|
|
40
|
+
}): CursorPriceAxisOverlay {
|
|
41
|
+
const labelText = cursorLabel === null
|
|
42
|
+
? null
|
|
43
|
+
: formatAxisCell(cursorLabel, axisWidth).padEnd(axisSectionWidth);
|
|
44
|
+
const pixelHeight = Math.max(height * cellHeightPx, 1);
|
|
45
|
+
let topPercent: number | null = null;
|
|
46
|
+
|
|
47
|
+
if (labelText && cursorPixelY !== null && cursorPixelY !== undefined && Number.isFinite(cursorPixelY) && pixelHeight > 1) {
|
|
48
|
+
const halfLabelHeight = Math.min(cellHeightPx / 2, (pixelHeight - 1) / 2);
|
|
49
|
+
const topPx = clamp(cursorPixelY, halfLabelHeight, Math.max(pixelHeight - halfLabelHeight, halfLabelHeight));
|
|
50
|
+
topPercent = (topPx / Math.max(pixelHeight - 1, 1)) * 100;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { labelText, topPercent };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function PriceAxisLabels({
|
|
57
|
+
axisLabels,
|
|
58
|
+
axisWidth,
|
|
59
|
+
axisSectionWidth,
|
|
60
|
+
height,
|
|
61
|
+
cursorRow,
|
|
62
|
+
cursorPixelY = null,
|
|
63
|
+
cursorLabel,
|
|
64
|
+
cursorColor,
|
|
65
|
+
}: PriceAxisLabelsProps) {
|
|
66
|
+
const { cellHeightPx = 18, fractionalViewport = false } = useUiCapabilities();
|
|
67
|
+
const overlay = useMemo(() => buildCursorPriceAxisOverlay({
|
|
68
|
+
axisWidth,
|
|
69
|
+
axisSectionWidth,
|
|
70
|
+
height,
|
|
71
|
+
cursorPixelY,
|
|
72
|
+
cursorLabel,
|
|
73
|
+
cellHeightPx,
|
|
74
|
+
}), [axisSectionWidth, axisWidth, cellHeightPx, cursorLabel, cursorPixelY, height]);
|
|
75
|
+
const usePixelOverlay = fractionalViewport && overlay.labelText !== null && overlay.topPercent !== null;
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<Box
|
|
79
|
+
width={axisSectionWidth}
|
|
80
|
+
height={height}
|
|
81
|
+
flexDirection="column"
|
|
82
|
+
overflow="hidden"
|
|
83
|
+
style={usePixelOverlay ? { position: "relative" } : undefined}
|
|
84
|
+
>
|
|
85
|
+
{Array.from({ length: height }, (_, row) => {
|
|
86
|
+
const isCursorRow = !usePixelOverlay && cursorLabel !== null && cursorRow === row;
|
|
87
|
+
const label = isCursorRow ? cursorLabel : (axisLabels.get(row) ?? null);
|
|
88
|
+
return (
|
|
89
|
+
<Text key={row} fg={isCursorRow ? cursorColor : colors.textDim}>
|
|
90
|
+
{formatAxisCell(label, axisWidth).padEnd(axisSectionWidth)}
|
|
91
|
+
</Text>
|
|
92
|
+
);
|
|
93
|
+
})}
|
|
94
|
+
{usePixelOverlay ? (
|
|
95
|
+
<Text
|
|
96
|
+
width={axisSectionWidth}
|
|
97
|
+
fg={cursorColor}
|
|
98
|
+
bg={colors.bg}
|
|
99
|
+
style={{
|
|
100
|
+
position: "absolute",
|
|
101
|
+
left: 0,
|
|
102
|
+
top: `${overlay.topPercent}%`,
|
|
103
|
+
transform: "translateY(-50%)",
|
|
104
|
+
whiteSpace: "pre",
|
|
105
|
+
pointerEvents: "none",
|
|
106
|
+
zIndex: 1,
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
{overlay.labelText}
|
|
110
|
+
</Text>
|
|
111
|
+
) : null}
|
|
112
|
+
</Box>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { Box, ChartSurface, Text, useNativeRenderer, useUiCapabilities } from "../../ui";
|
|
3
|
+
import { useThemeColors } from "../../theme/theme-context";
|
|
3
4
|
import type { ProjectedChartPoint } from "./chart-data";
|
|
4
5
|
import {
|
|
5
6
|
buildChartScene,
|
|
@@ -45,6 +46,7 @@ export function StaticChartSurface({
|
|
|
45
46
|
yAxisColor,
|
|
46
47
|
formatYAxisValue,
|
|
47
48
|
}: StaticChartSurfaceProps) {
|
|
49
|
+
useThemeColors();
|
|
48
50
|
const {
|
|
49
51
|
canvasCharts,
|
|
50
52
|
nativeCharts,
|
|
@@ -9,6 +9,7 @@ import { ShortcutHint } from "../ui";
|
|
|
9
9
|
import { saveConfig } from "../../data/config-store";
|
|
10
10
|
import { getSharedMarketData } from "../../plugins/registry";
|
|
11
11
|
import { colors } from "../../theme/colors";
|
|
12
|
+
import { useThemeColors } from "../../theme/theme-context";
|
|
12
13
|
import { formatCompact } from "../../utils/format";
|
|
13
14
|
import { formatMarketPriceWithCurrency } from "../../utils/market-format";
|
|
14
15
|
import { useChartQueries, useChartQuery } from "../../market-data/hooks";
|
|
@@ -82,7 +83,6 @@ import {
|
|
|
82
83
|
} from "./chart-viewport";
|
|
83
84
|
import {
|
|
84
85
|
buildChartScene,
|
|
85
|
-
formatAxisCell,
|
|
86
86
|
formatCursorAxisValue,
|
|
87
87
|
getActivePointIndex,
|
|
88
88
|
getPointTerminalColumn,
|
|
@@ -128,6 +128,7 @@ import {
|
|
|
128
128
|
import type { PricePoint, TickerFinancials } from "../../types/financials";
|
|
129
129
|
import type { TickerRecord } from "../../types/ticker";
|
|
130
130
|
import { TimeAxisLabel } from "./time-axis-label";
|
|
131
|
+
import { PriceAxisLabels } from "./price-axis-labels";
|
|
131
132
|
|
|
132
133
|
const MODE_CHIPS: Record<ChartRenderMode, string> = {
|
|
133
134
|
area: "A",
|
|
@@ -1436,6 +1437,7 @@ export const ResolvedStockChart = memo(function ResolvedStockChart({
|
|
|
1436
1437
|
ticker,
|
|
1437
1438
|
financials,
|
|
1438
1439
|
}: ResolvedStockChartProps) {
|
|
1440
|
+
const themeColors = useThemeColors();
|
|
1439
1441
|
const renderer = useNativeRenderer();
|
|
1440
1442
|
const { canvasCharts, cellWidthPx = 8, cellHeightPx = 18, pixelRatio = 1 } = useUiCapabilities();
|
|
1441
1443
|
const dispatch = useAppDispatch();
|
|
@@ -3013,15 +3015,24 @@ export const ResolvedStockChart = memo(function ResolvedStockChart({
|
|
|
3013
3015
|
: 0;
|
|
3014
3016
|
const trend = rawChange < 0 ? "negative" : rawChange > 0 ? "positive" : "neutral";
|
|
3015
3017
|
return resolveChartPalette({
|
|
3016
|
-
bg:
|
|
3017
|
-
border:
|
|
3018
|
-
borderFocused:
|
|
3019
|
-
text:
|
|
3020
|
-
textDim:
|
|
3021
|
-
positive:
|
|
3022
|
-
negative:
|
|
3018
|
+
bg: themeColors.bg,
|
|
3019
|
+
border: themeColors.border,
|
|
3020
|
+
borderFocused: themeColors.borderFocused,
|
|
3021
|
+
text: themeColors.text,
|
|
3022
|
+
textDim: themeColors.textDim,
|
|
3023
|
+
positive: themeColors.positive,
|
|
3024
|
+
negative: themeColors.negative,
|
|
3023
3025
|
}, trend);
|
|
3024
|
-
}, [
|
|
3026
|
+
}, [
|
|
3027
|
+
chartWindow.points,
|
|
3028
|
+
themeColors.bg,
|
|
3029
|
+
themeColors.border,
|
|
3030
|
+
themeColors.borderFocused,
|
|
3031
|
+
themeColors.negative,
|
|
3032
|
+
themeColors.positive,
|
|
3033
|
+
themeColors.text,
|
|
3034
|
+
themeColors.textDim,
|
|
3035
|
+
]);
|
|
3025
3036
|
|
|
3026
3037
|
const cursorX = viewState.cursorX !== null ? clamp(viewState.cursorX, 0, chartWidth - 1) : null;
|
|
3027
3038
|
const cursorY = viewState.cursorY !== null ? clamp(viewState.cursorY, 0, chartHeight - 1) : null;
|
|
@@ -3437,6 +3448,7 @@ export const ResolvedStockChart = memo(function ResolvedStockChart({
|
|
|
3437
3448
|
timeLabels={timeAxisLabel}
|
|
3438
3449
|
width={chartWidth}
|
|
3439
3450
|
cursorColumn={cursorTimeAxisColumn}
|
|
3451
|
+
cursorPixelX={hasDisplayCursor ? displayCursor.pixelX : null}
|
|
3440
3452
|
cursorDate={cursorTimeAxisDate}
|
|
3441
3453
|
dates={timeAxisDates}
|
|
3442
3454
|
cursorColor={chartColors.crosshairColor}
|
|
@@ -3955,17 +3967,16 @@ export const ResolvedStockChart = memo(function ResolvedStockChart({
|
|
|
3955
3967
|
);
|
|
3956
3968
|
|
|
3957
3969
|
const axisBox = (
|
|
3958
|
-
<
|
|
3959
|
-
{
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
</Box>
|
|
3970
|
+
<PriceAxisLabels
|
|
3971
|
+
axisLabels={axisLabels}
|
|
3972
|
+
axisWidth={axisWidth}
|
|
3973
|
+
axisSectionWidth={axisSectionWidth}
|
|
3974
|
+
height={chartHeight}
|
|
3975
|
+
cursorRow={cursorRow}
|
|
3976
|
+
cursorPixelY={hasDisplayCursor ? displayCursor.pixelY : null}
|
|
3977
|
+
cursorLabel={cursorAxisLabel}
|
|
3978
|
+
cursorColor={chartColors.crosshairColor}
|
|
3979
|
+
/>
|
|
3969
3980
|
);
|
|
3970
3981
|
|
|
3971
3982
|
if (compact) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { Span, Text } from "../../ui";
|
|
2
|
+
import { Box, Span, Text, useUiCapabilities } from "../../ui";
|
|
3
3
|
import { colors } from "../../theme/colors";
|
|
4
4
|
import { buildCursorTimeAxisSegments } from "./chart-renderer";
|
|
5
5
|
|
|
@@ -7,19 +7,60 @@ interface TimeAxisLabelProps {
|
|
|
7
7
|
timeLabels: string;
|
|
8
8
|
width: number;
|
|
9
9
|
cursorColumn: number | null;
|
|
10
|
+
cursorPixelX?: number | null;
|
|
10
11
|
cursorDate: Date | string | number | null;
|
|
11
12
|
dates: Array<Date | string | number>;
|
|
12
13
|
cursorColor: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
interface CursorTimeAxisOverlay {
|
|
17
|
+
baseText: string;
|
|
18
|
+
label: string | null;
|
|
19
|
+
leftPercent: number | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function clamp(value: number, min: number, max: number): number {
|
|
23
|
+
return Math.max(min, Math.min(max, value));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function buildCursorTimeAxisOverlay({
|
|
27
|
+
segments,
|
|
28
|
+
width,
|
|
29
|
+
cursorPixelX,
|
|
30
|
+
cellWidthPx,
|
|
31
|
+
}: {
|
|
32
|
+
segments: ReturnType<typeof buildCursorTimeAxisSegments>;
|
|
33
|
+
width: number;
|
|
34
|
+
cursorPixelX: number | null | undefined;
|
|
35
|
+
cellWidthPx: number;
|
|
36
|
+
}): CursorTimeAxisOverlay {
|
|
37
|
+
const baseText = segments
|
|
38
|
+
.map((segment) => (segment.highlighted ? " ".repeat(segment.text.length) : segment.text))
|
|
39
|
+
.join("")
|
|
40
|
+
.padEnd(width)
|
|
41
|
+
.slice(0, width);
|
|
42
|
+
const label = segments.find((segment) => segment.highlighted)?.text ?? null;
|
|
43
|
+
const pixelWidth = Math.max(width * cellWidthPx, 1);
|
|
44
|
+
let leftPercent: number | null = null;
|
|
45
|
+
if (label && cursorPixelX !== null && cursorPixelX !== undefined && Number.isFinite(cursorPixelX) && pixelWidth > 1) {
|
|
46
|
+
const halfLabelWidth = Math.min((label.length * cellWidthPx) / 2, (pixelWidth - 1) / 2);
|
|
47
|
+
const leftPx = clamp(cursorPixelX, halfLabelWidth, Math.max(pixelWidth - halfLabelWidth, halfLabelWidth));
|
|
48
|
+
leftPercent = (leftPx / Math.max(pixelWidth - 1, 1)) * 100;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { baseText, label, leftPercent };
|
|
52
|
+
}
|
|
53
|
+
|
|
15
54
|
export function TimeAxisLabel({
|
|
16
55
|
timeLabels,
|
|
17
56
|
width,
|
|
18
57
|
cursorColumn,
|
|
58
|
+
cursorPixelX = null,
|
|
19
59
|
cursorDate,
|
|
20
60
|
dates,
|
|
21
61
|
cursorColor,
|
|
22
62
|
}: TimeAxisLabelProps) {
|
|
63
|
+
const { cellWidthPx = 8, fractionalViewport = false } = useUiCapabilities();
|
|
23
64
|
const segments = useMemo(() => buildCursorTimeAxisSegments({
|
|
24
65
|
timeLabels,
|
|
25
66
|
width,
|
|
@@ -27,6 +68,42 @@ export function TimeAxisLabel({
|
|
|
27
68
|
cursorDate,
|
|
28
69
|
dates,
|
|
29
70
|
}), [cursorColumn, cursorDate, dates, timeLabels, width]);
|
|
71
|
+
const overlay = useMemo(() => buildCursorTimeAxisOverlay({
|
|
72
|
+
segments,
|
|
73
|
+
width,
|
|
74
|
+
cursorPixelX,
|
|
75
|
+
cellWidthPx,
|
|
76
|
+
}), [cellWidthPx, cursorPixelX, segments, width]);
|
|
77
|
+
|
|
78
|
+
if (fractionalViewport && overlay.label && overlay.leftPercent !== null) {
|
|
79
|
+
return (
|
|
80
|
+
<Box
|
|
81
|
+
width={width}
|
|
82
|
+
height={1}
|
|
83
|
+
overflow="hidden"
|
|
84
|
+
style={{ position: "relative" }}
|
|
85
|
+
>
|
|
86
|
+
<Text fg={colors.textDim} style={{ whiteSpace: "pre" }}>
|
|
87
|
+
{overlay.baseText}
|
|
88
|
+
</Text>
|
|
89
|
+
<Text
|
|
90
|
+
fg={cursorColor}
|
|
91
|
+
bg={colors.bg}
|
|
92
|
+
style={{
|
|
93
|
+
position: "absolute",
|
|
94
|
+
left: `${overlay.leftPercent}%`,
|
|
95
|
+
top: 0,
|
|
96
|
+
transform: "translateX(-50%)",
|
|
97
|
+
whiteSpace: "pre",
|
|
98
|
+
pointerEvents: "none",
|
|
99
|
+
zIndex: 1,
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{overlay.label}
|
|
103
|
+
</Text>
|
|
104
|
+
</Box>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
30
107
|
|
|
31
108
|
return (
|
|
32
109
|
<Text style={{ whiteSpace: "pre" }}>
|
|
@@ -25,34 +25,6 @@ exports[`CommandBar renders the default layout with opencode-style chrome 1`] =
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
"
|
|
29
|
-
`;
|
|
30
|
-
|
|
31
|
-
exports[`CommandBar renders theme prefix results in the root query 1`] = `
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
Commands
|
|
35
|
-
TH
|
|
36
|
-
|
|
37
|
-
Themes
|
|
38
|
-
Amber current
|
|
39
|
-
Green Phosphor
|
|
40
|
-
Cyan
|
|
41
|
-
Red Phosphor
|
|
42
|
-
Blue Phosphor
|
|
43
|
-
Purple Phosphor
|
|
44
|
-
Hot Pink
|
|
45
|
-
White Phosphor
|
|
46
|
-
Tokyo Night
|
|
47
|
-
Solarized Dark
|
|
48
|
-
Dracula
|
|
49
|
-
Nord
|
|
50
|
-
Monokai
|
|
51
|
-
Catppuccin Mocha
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
28
|
"
|
|
57
29
|
`;
|
|
58
30
|
|